jquery or javascript: Truncate text in table cell - javascript

I need to truncate the text in the first column of a table using javascript or jQuery. Here's where I'm at:
The table:
<table id="bigTable">
<tr><td>Text is tooooo looong</td><td>Just Right</td></tr>
<tr><td>Text is tooooo looong</td><td>Just Right</td></tr>
<tr><td>Text is tooooo looong</td><td>Just Right</td></tr>
</table>
Trying stuff like the following without success ( compiled from other similar posts ):
var lbl = $("#bigTable tbody");
var newLbl = $(lbl[0].outerHTML);
$('td:eq(0)', newLbl).slice(5);
It does not seem to be getting the contents, or text from the cells. Has no effect whatsoever. Tried also -
$('td:eq(0)', newLbl)contents().slice(5);
$('td:eq(0)', newLbl).text().slice(5);
What am I doing wrong?
EDIT
Before more down-voting and general grumpy-ness occurs ...
I have to have the text from a div copied to a variable for manipulation and later display in a different window/div.
This happens in response to a button click.
...but applying the css rules sounds promising. Will try that instead.
Please see this fiddle to understand what I need to do:
http://jsfiddle.net/Vsse3/2/
I have to be able to wrap column cells with a div before using the css idea.

You don't need js, using CSS:
demo:
http://jsfiddle.net/vTDAQ/3/
#elckarns comment is correct but you also need to wrap the cell content in a div to use text-overflow.
Also note that your table is not well formed.
demo updated as requested:
http://jsfiddle.net/Vsse3/6/

Related

jQuery DataTables: Avoid linebreaks in cells

I don't have a CSS problem, but a logical problem. I want to get rid of automatic linebreaks in my table cells. For some reason, long pieces of data are split in two lines, even in the HTML itself. This means that none of the classic CSS attributes are going to help here.
Example:
<td class="sorting_1">SAP-IT Projekt
Welle 1</td>
The value inside of the td element is cut in two.
What I've tried:
{
"data": "Project.Name",
"editField": "ProjectEntry.IdProject",
"render": function (project) {
// This code doesn't really work, the cells still contain linebreaks.
project = project.trim().replace(/(\r\n\t|\n|\r\t)/gm, "");
console.log(project);
return project;
}
}
Note: The logging in this render function outputs the string without linebreaks.
I think I'm missing a crucial piece of configuration that prevents these automatic linebreaks.
The table used to have the "responsive" piece of configuration, but I've removed that.
Update:
Here's the style of each cell:
#ProjectEntryDataContainer, #ProjectEntryDataContainer > div > table > tbody > tr > td {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
table-layout: fixed;
}
This style is being applied to each cell, according to Chrome's DevTools. The table element hast the class nowrap.
As I've mentioned, the CSS has little to nothing to do with my issue. The text is being displayed in one line, but the HTML element has a line break in it. I want to get rid of the line break in my HTML so I can search the cells properly, using jQuery code. I'm currently using the following code to search my cells:
var project = rowData.Project.Name.trim().replace(/(\r\n\t|\n|\r\t)/gm, "");
// Find our required cell that we want to edit. If we can't find one, create a new one.
var colHeaderTarget = $("#ProjectEntryData").find('th:contains("Arbeitsstunden")')[0];
var rowHeaderTarget = $("#ProjectEntryData").find('td:contains("' + project + '")')[0];
var projectRows = $("#ProjectEntryData").find("tr:contains('" + project + "')");
console.log(project);
console.log(projectRows);
This code works wonderfully as long as the cell doesn't have linebreaks.
I just found out that my JSON data contains linebreaks. I'll update once I find out more.
{IdProject: 35, Name: "SAP-IT Projekt
↵ Welle 1", Description: null,
Update: The SQL data contained linebreaks... See answer.
Turns out that when your database contains line breaks you're going to get line breaks in the HTML. If anyone has a solution that causes DataTables to filter out line breaks in the cell data, I'll mark that one as the accepted answer. Otherwise, I'll just advise everyone to avoid linebreaks in your SQL data.
try it worked for me very well.

Rendering dynamic Enyo Repeaters

I need to make a data table for an enyo project I am working on that will ultimately display the result of an Ajax call.
This (Blatantly stolen from ryanjduffy here)seems to be a good starting point, but when I try to call setData() from a button event (rather than in the constructor) as I have here I get the following error:
InvalidCharacterError: String contains an invalid character # http://enyojs.com/enyo-2.1/enyo/source/dom/Control.js:681
I looked at the Control.js code and it seems that it tries to create a new node, but the this.tag property is set to null and things break.
I feel like I am missing something really simple, but I just can't see the problem yet...
Can someone tell me what I am doing wrong?
Thanks!
EDIT 1:
Apparently calling render() is not needed. Here is the original working version with render() commented out. Everything looks great. However, if I try to remove render() from the version that requires a button click, the repeater starts creating div's above the table instead of tr td's inside the table...
EDIT 2:
Basically, from what I can tell, the Repeater inside of a table will lose it's parent once the table is rendered (or something like that). The result is the Repeater will start rendering its new items outside of the original table and because a td tag without a table makes no sense, it just renders a div.
The solution I have come up with is to give the Repeater itself a table tag so its children always wind up in the right spot. This adds the challenge of needing to recreate the header line each time, but it is not that big of a deal. I have a working example if anyone is interested.
I'm sure you're not looking for a solution any longer but since I was mentioned in the post, I thought I'd let you know what I figured out. In short, my code shouldn't have worked but since browsers are forgiving, it did ... sort of.
When the code run at create time, it renders something like this:
<table>
<tr> <!-- header row --> </tr>
<div> <!-- repeater tag -->
<tr> <!-- repeater row --> </tr>
</div>
</table>
The browser looks at that and says, "Hey, dummy! No <div>s in a <table>" and kicks it out but leaves the <tr>s.
In your example, since you're delaying the render of the rows, Enyo renders:
<table>
<tr> <!-- header row --> </tr>
<div></div>
</table>
And the browser ejects the <div> and you're left with an empty table. When you later set the data, those rows are rendered into the div. Unfortunately, since you're rendering <tr> and <td>, those aren't valid outside a table so you just get text.
I found a couple solutions. The simplest was to set the tag of the Repeater to be TBODY which is allowed inside a table. The slightly more involved solution was to make the DataTable inherit from Repeater and set the header row to be chrome so they're not removed when updating the data.
Option #2 Fiddle
enyo.kind({
name:"DataTable",
tag: "table",
kind: "Repeater",
published:{
map:0,
data:0
},
handlers: {
onSetupItem: "setupItem"
},
components:[
{name:"row", kind:"DataRow"}
],
create:function() {
this.inherited(arguments);
this.mapChanged = this.dataChanged = enyo.bind(this, "refresh");
this.refresh();
},
refresh:function() {
if(this.map && this.data) {
this.buildHeader();
this.setCount(this.data.length);
}
},
buildHeader:function() {
if(this.$.header) {
this.$.header.destroyClientControls();
} else {
this.createComponent({name:"header", tag:"tr", isChrome: true});
}
for(var i=0;i<this.map.length;i++) {
this.$.header.createComponent({content:this.map[i].header, tag:"th"});
}
this.$.header.render();
},
setupItem:function(source, event) {
for(var i=0;i<this.map.length;i++) {
event.item.$.row.createComponent({content:this.data[event.index][this.map[i].field]});
}
event.item.render();
return true;
}
});

jQuery break out of table

I have a standard HTML formatted table, that dynamically generates the content, via Zend Framework. From which I have an issue altering the form internally PHP side. So I need to alter the tables appearance somehow. With that on the occasion I have an element show up in one of the rows and when this element shows up I want to break out of the table and then do something after it then start the table again.
Basically I want to inject the equivlant of
</tbody></table>/*other stuff*/<table><tbody> after the row containing the one element I seek which in this case is a label.
I tried $("label[for='theLable']").parents('tr').after('</tbody></table><br><table><tbody>') which appears to ignore the ending table parts add the br, and then does a complete open/close tag for table and tbody within the same table I am trying to break out of so inbetween tr tags basically it adds this new table
Whats the best way to approach this concept?
update with jsfiddle link
http://jsfiddle.net/cPWDh/
You can't really modify the HTML of the document the way you're thinking, since it's not a legitimate way to alter the DOM.
Instead, I would create a new table and .append the rows you want to move to it, which will automatically move them from their current location (instead of copying them):
$(document).ready(function() {
var $trow = $('label[for="specialLabel"]').closest('tr'),
$table = $trow.closest('table');
$('<table>').append( $trow.nextAll().andSelf() ).insertAfter($table);
});​
http://jsfiddle.net/cPWDh/1/
this approach won't work in js. What you could do if the table has not too many rows is this:
var nextTable = $("table").after("/*other stuff*/<table id="nextTable"></table>");
//now you loop over the lines of your original table that you want to have after the "break", and move them to the nextTable:
var before = true;
$("table tr").each(function(){
if ($(this).has("[for='theLable']")) {
before = false;
}
if (!before) {
nextTable.append($(this));
}
});

extracting text from html file

I'm trying to get nodes containing text from html file using Javascript and jQuery.
if I have a node like
`
<div>txt0
<span>txt1</span>
txt2
</div>
How can I select elements that meets this criteria??
Meaning, I need to retrieve thedivand thespan` , and it would be even better to know location of the text.
I'm trying to get the text to replace it with images in a later function.
I tried this
`
$('*').each(function(indx, elm){
var txt = $(elm).text();
// my code to replace text with images here
});
`
but it does not get the required results.. it does all the parsing in the first element, and changes the html totally.
I don't know exactly what you're trying to solve, but perhaps you can be a bit more specific with your selector?
$("div span").text(); // returns 'txt1'
$("div").text(); // returns 'txt0txt1txt2'
By adding ids and/or classes to your html, you can be very specific:
<div class="name">Aidan <span class="middlename">Geoffrey</span> Fraser</div>
...
// returns all spans with class
// "middlename" inside divs with class "name"
$("div.name span.middlename").text();
// returns the first span with class
// "middlename" inside the fourth div
// with class "name"
$("div.name[3] span.middlename[0]").text();
JQuery has pretty good documentation of these selectors.
If this doesn't help, consider explaining the problem you're trying to solve.
Your markup structure is a bit uneasy. Consider changing to something like this
<div>
<span>txt0</span>
<span>txt1</span>
<span>txt2</span>
</div>
Then using jQuery
$("div span").each(function(k,v) {
$(this).html("<img src=\""+v+".jpg\" />"); //replace with the image
});

.focus() doesn't work on an input while orher attributes works

I have a classic table / thead / tbody structure, which I add a line at the end of the tbody. The line contains only an input element. The code works in Firefox 3.6 but not in Chrome v5 or IE8. I'm using jQuery 1.4.2.
Does not work:
$("#" + AJAX_ID).parent().find('tr:last > td:nth-child(2) > input').focus();
Does work:
$("#" + AJAX_ID).parent().find('tr:last > td:nth-child(2) > input').css('background-color', 'red');
even setting an ID on the input, and using document.getElementBuId('id').focus() doesn't work.
*** edit ***
The site is pretty complex (mix of template / static html and dynamic html), but the table
looks like this (rendered html in chrome, layout via tidy) : http://pastebin.com/PHqxAEVm
*** edit 2 ***
Even $("#lectures").find("input:last").focus(); called from the ajax callback doesn't do anything.. $("#lectures").find("input:last").css('background-color', 'red'); turns one red though, but the focus goes to the address bar.
Here's a dump of the returned object from the selector:
http://pastebin.com/Jdw1TZXf
*** edit 3 ***
Here's the JavaScript code that builds the table: http://pastebin.com/cbCfi0UY
on page load, oContainer is $("#lectures") while after the ajax call it's $("#" + AJAX_ID).parent(), which is supposed to point to the table's tbody
*** edit 4 ***
Hard problem... here's the full lectures.js file: http://pastebin.com/Jkg0DZqa
batisses and compteurs are json objects loaded via the template. the user select a batisse then a compteur then press a button that calls buildAjout(), which calls in this example buildElectric($("#lectures"), compteur);. Once the line is filled bu the user, onBlurLecture(tr_parent) is called, the data is sent to the server via AJAX and function callback_compteurs_lecture_add(AJAX_ID) is called after the ajax call is complete. The function SendCommand is a custom function which use jQuery ajax.
The creation of the first input line (and the focus) works, but not the one created in the callback of the ajax.
*** edit 5 ***
The full rendered page looks like: http://pastebin.com/UfBYcjX3
I shortened the batisses variable. The (full) page has no JavaScript errors.
In Chrome's JavaScript console, I cannot focus the inputs.
*** edit 6 ***
Wrong function name in this question for SendCommand. fixed.
Solution found:
.focus() doesn't work on an input while orher attributes works
What ID are you targeting? Because if I replace $("#" + AJAX_ID) with $('table') it works -> demo (at least in Chrome)
and if I wrap the function inside a $(document).ready(function(){...}) it works in IE -> demo
I'm still looking to see what the problem might be, but I have a few comments about your code so far.
I haven't tested this, but I creating a jQuery object then appending another object inside ends up taking a lot of time because of the number of function calls. I've found it easier to just build up a string and only use one append. This example makes it easy to read:
var table = '\
<table style="width: 100%">\
<thead>\
<tr>\
<th>Numéro</th>\
<th>litre</th>\
<th style='width: 100px;'>Status</th>\
</tr>';
// append more to the string
table += '<tbody>.....</tbody></table>';
$('body').append(table);
I found this bit of code and I just wanted to show you that you can shorten it:
$("#no_batisse").css('display', 'none');
$("#lectures").html("");
$("#lectures").css('display', '');
shortens to:
$("#no_batisse").hide();
$("#lectures").empty().hide();
Instead of calling this function after each row addition, you could try adding a live function once that works with dynamically added content:
$(oLigne).find("input").blur(function() { onBlurLecture(oLigne); });
try running this when you initialize the script (just once)
$('#lecture').find('input').live('blur', function(){
onBlurLecture( $(this).closest('tr') );
})
I'll keep looking!
EDIT:
If your code is being triggered via some element that has a default behavior (like an <a> element), try adding return false; to the end of its callback.
Alternatively, if you give a parameter to the event handler's function, like function(e) {...}, you can call e.preventDefault() from within the callback instead of return false;.
First, I don't know if this is the issue, but IDs can not start with a number.
Second, which element has the AJAX ID that are you using? You'll get different results depending on that.
To avoid any ID issues, you could do:
$("#lectures").find('tr:last > td:nth-child(2) > input').focus();
or if you want it to be relative, do:
$("#" + AJAX_ID).closest('tbody').find('tr:last > td:nth-child(2) > input').focus();
got it!
I use "tab" (tabulation) to switch to the next input while writing in them. At the last one, the focus goes out of the window so I cannot set it. I converted the last column "status" into a input so it gets the focus while onBlur is executed. When the ajax load callback is called, the new line is added and the input is focused as it should.
Chrome: works
Firefox: works
IE8: works (with fix)
spent 1½ day on that lol
thanks everyone!
Try to trigger .focusin() (this was added in jQuery's 1.4) See documentation.

Categories

Resources