I'm having a couple of issue with Jquery. Basically I have a .html() response printed and I have to highlight rows of a table on mouseover but it doesn't work.
HTML table
<table id='simplehighlight'>
<tr>
<td>header 1</td>
<td>header 2</td>
</tr>
<tr>
<td>bla bla bla</td>
<td>highlight this row</td>
</tr>
<tr>
<td>bla bla bla</td>
<td>or highlight this row</td>
</tr>
</table>
the table above is printed with PHP echos. The PHP script is called with ajax and the response is printed inside a div with the .html() function. Example:
function(data, textStatus) {
if(textStatus == "success") {
$('#resultBox').html(data);
}
}, 'text/html');
}
data is the HTML table. Last but not least I have the jquery code for active the highlight which it doesn't work.
$("simplehighlight tr").not(':first').hover(
function () {
$(this).css("background","yellow");
},
function () {
$(this).css("background","");
}
);
instead of highlighting the row I have put a simple alert to check if it works, but obviusly it does not. Why? What's wrong in my code? How can I accomplish my task, aka highlight these rows?
Thanks everyone,
Alberto-
Attaching an event handler via jQuery's on should work:
$('body').on('mouseenter mouseleave', '#simplehighlight tr:not(:first-child)', function() {
$( this ).toggleClass( 'highlighted' );
} );
See this jsFiddle.
The good thing with using on this way is, that the table you mentioned may be added at any time (e.g. through an AJAX call). When calling on directly on the jQuery match (as in jQuery("#simplehighlight tr").not(':first').on(...)), jQuery binds the handler only to the currently existing DOM elements.
Note: I replaced the hover event with mouseenter mouseleave, because hover is removed since jQuery 1.9:
Deprecated in jQuery 1.8, removed in 1.9: The name "hover" used as a
shorthand for the string "mouseenter mouseleave".
Source: http://api.jquery.com/on/
You have to remember that commands such as the one your are trying to execute, will only be executed against elements that already exist in your DOM. So basically you have to combine the two segments of your code like this:
function(data, textStatus) {
if(textStatus == "success") {
$('#resultBox').html(data);
$("simplehighlight tr").not(':first').hover(
// do highlight stuffs here
alert("IT WORKS??");
});
}
}, 'text/html');
}
Instead of firing the hover() function manually, you should set up an event handler to do so. Events will also get captured from inserted elements; so you may set up the event listener even before the AJAX call.
jQuery( 'simplehighlight tr' ).not(':first').on( 'hover', function() {
var currentTR = jQuery( this );
currentTR.addClass( 'highlight' );
} );
try
jQuery("#simplehighlight tr").not(':first').mouseover(function(){
// do highlight stuffs here
alert("IT WORKS??");
});
here a js fiddle
here
Related
I have a React component for a table. If the user is not me, then when I see that user's profile page, I only see the first three columns of the table. If the user is me, then I see four columns. However, dynamically changing the columns causes the following error:
Uncaught Error: Invariant Violation: processUpdates(): Unable to find child 3 of element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a <tbody> when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG elements in an <svg> parent. Try inspecting the child nodes of the element with React ID `.0.1.1.0.0.1.0.0`.
I've looked around a lot and made sure that my table is encased with . How can I allow for this table flexibility in React?
My outer table shell looks like this:
var CategoriesTable = React.createClass({
render: function() {
var includeReps = false;
var repsHeader = '';
if (this.props.currentUser.username === this.props.user.username) {
includeReps = true;
repsHeader = <th>Reps</th>;
}
return (
<div className="categoriesTable panel panel-default">
<CategoriesHeader user={this.props.user} />
<table className="table table-bordered table-striped">
<tbody>
<tr>
<th>Category</th>
<th>Direct Rep</th>
<th>Crowd Rep</th>
{repsHeader}
</tr>
{this.props.user.categories.map(function(category) {
return <CategoriesItem key={category.id} category={category.name} directRep={category.directScore} prevDirectRep={category.previousDirectScore} crowdRep={category.crowdScore} reps={category.reps} includeReps={includeReps} />;
})}
</tbody>
</table>
</div>
);
}
});
Each table row looks like this:
var CategoriesItem = React.createClass({
render: function() {
var reps = this.props.includeReps ? <td>{this.props.reps}</td> : '';
return (
<tr className="categoriesItem">
<td>{this.props.category}</td>
<td><ScoreBar directRep={this.props.directRep} prevDirectRep={this.props.prevDirectRep} category={this.props.category}/></td>
<td>{this.props.crowdRep}</td>
{reps}
</tr>
);
}
});
Why can I do to make React accept these table changes? When I start with the table with all four columns and then switch to a different user's profile page, the fourth table data piece becomes a
Perhaps a hack, but giving a react component a key will force the entire component to re-render when the key changes. If each profile page gives the table a unique key, then this problem goes away.
Since I don't know much about jQuery I have am not being able to produce a dialog box on hover over a checkbox. Any suggestion would be helpful. Below is my code:
<input type="checkbox" id="employee-id" name="employeeId" onmouseover="produceDialog()">
<div id="employee-info-div"></div>
Similarly my jQuery is:
produceDialog(){
$("employee-info-div").dialog({
open : function ( event, ui ) {
$(".ui-dialog-titlebar-close").hide();
},
dialogClass : 'fixed-dialog',
resizable : false,
height : 150,
width : 250,
modal : false,
create : function ( event ) {
$(event.target).parent().css('position', 'fixed');
},
});
}
This may be the example you are looking for:
Working jsFiddle here
Below is a stand-alone example, which should just be copy/play.
Notes:
The element $('#employee-info-div'); was assigned to a variable to make code more efficient and faster to type. (More efficient b/c only check DOM once for the element, retrieve from variable after that.)
Used jQuery hover() method to open the dialog, but initialized the dialog separately (upon document ready). Note that the hover method must have two functions associated with it; the second function need not do anything but it must be there.
The hover-IN method assigned to the class $('.employee-id') runs the code $('#employee-info-div').dialog('open');, which opens the dialog. Note that the 2nd element is accessed via variable name.
Copy/Paste the following code into a separate document in your webroot and run, OR just use the above jsFiddle link to see it all in action.
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css" />
<style>
#employee-info-div{
width:40%;
float:right;
padding:5px;
background:wheat;
color:blue;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
var eid = $('#employee-info-div');
var blurb = '<h2>Employee Information:</h2>Here is some example information about this employee. It can be text inserted like this, or it can be information retrieved from a database via AJAX. For simple AJAX examples, <a target="_blank" href="http://stackoverflow.com/questions/17973386/ajax-request-callback-using-jquery/17974843#17974843"> see this StackOverflow post </a> (remember to upvote any posts that are helpful to you, please.)';
function hovIn() {
$(this).css({'font-weight':'bold','color':'blue'});
eid.html(blurb);
eid.dialog('open');
}
function hovOut() {
//eid.html(''); //<-- Causes dlg text to appear/disappear as you move mouse on/off checkbox and label
$(this).css({'font-weight':'normal','color':'black'});
}
$('.employee-id').hover(hovIn, hovOut);
eid.dialog({
autoOpen:false,
title:"Your jQueryUI Dialog",
show: "fade",
hide: "fade",
width:500, //orig defaults: width: 300, height: auto
buttons: {
Ok: function() {
$(this).dialog('close');
}
}
}); //END eid.dialog
}); //END $(document).ready()
</script>
</head>
<body>
Hover over below checkbox to see hidden DIV:<br><br>
<input type="checkbox" id="employee-id" class="employee-id" name="employeeId" ><span class="employee-id">Hover over this checkbox</span>
<div id="employee-info-div"></div>
</body>
</html>
You can bind the hover event to your checkbox:
$("#employee-id").hover(function(){
// call your produceDialog function here
});
I have the below content that loads on through AJAX.
<div class="grid">
<div class="thumb">
<img alt="AlbumIcon" src="some-image.jpg">
<div style="bottom:-75px;" class="meta">
<p class="title">Title</p>
<p class="genre"> <i class="icon-film icon-white"></i>
Genre
</p>
</div>
</div>
</div>
Additionally, I have writen the following script in jquery that applies to the above 'div.grid'.
jQuery(function ($) {
$(document).ready(function () {
$(".grid").on({
mouseenter : function () {
$(this).find('.meta').stop().animate({
bottom:'0px'
},200);
},
mouseleave : function () {
$(this).find('.meta').stop().animate({
bottom:'-75px'
},200);
}
});
});
});
The script works fine when the page loads the first time. However, the hover effect doesn't work once the above div is generated via AJAX after clicking on an 'a' tag. I can't seem to figure out what's wrong here? New to all this. Can anyone help?
To append these event handlers to dynamically generated elements, you need to bind to the document or another static parent element and then specify .grid as the second argument passed to .on.
The second argument is used as a filter to determine the selected elements that trigger the event. So when the event is fired it will propagate to the document or parent element selected by jquery. The event target will then be scrutinized using the selector provided as the second argument. If the target matches the second argument, (.grid in our case), the event is fired.
You can read more in the jQuery documentation.
Also, since your using document.ready there is no need for the short hand ready statement, jquery(function($).
$(document).ready(function () {
$(document).on({
mouseenter : function () {
$(this).find('.meta').stop().animate({
bottom:'0px'
},200);
},
mouseleave : function () {
$(this).find('.meta').stop().animate({
bottom:'-75px'
},200);
}
}, ".grid");
});
you lost your binding because of ajax that overwrite your div with class=".grid"
use parent element for binding
$('.ParentElementClass').on("mouseleave", ".grid", function(){...})
more from jquery api
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers. This element could be the container element of a view in a Model-View-Controller design, for example, or document if the event handler wants to monitor all bubbling events in the document. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready.
Not sure what you're shooting for here but a little malformed HTML may have done it...
jsFiddle Demo
<div class="grid">
<div class="thumb">
<img alt="AlbumIcon" src="some-image.jpg" />
<div style="bottom:-75px;" class="meta">
<p class="title">Title</p>
<p class="genre"><i class="icon-film icon-white"></i>Genre</p>
</div>
</div>
</div>
$(function () {
$(".grid").on({
mouseenter: function () {
alert('entered');
$(this).find('.meta').stop().animate({
bottom: '0px'
}, 200);
},
mouseleave: function () {
alert('left');
$(this).find('.meta').stop().animate({
bottom: '-75px'
}, 200);
}
}, ".thumb");
});
});
Be sure to close img tags. They're notorious for causing intermittent glitches.
You can just use the hover function:
jQuery(function ($) {
$(document).ready(function () {
$(".grid").hover(function () { /*mouseenter*/
$(this).find('.meta').stop().animate({
bottom:'0px'
},200);
},function(){ /*mouseleave*/
$(this).find('.meta').stop().animate({
bottom:'-75px'
},200);
}
});
});
Explanation:
The first parameter function does the work of mouseenter and the second does the work of mouseleave.
I'd recommend using those both, mouseenter and mouseleave in situation when you don't want an effect back when the user gets off his mouse from the element.
I have the following html code:
<table id="MatrixTable">
<tr>
<td id="321"> 0 </td>
</tr>
</table
A. How can I replace the '0' text with an hyperlink when mouseover with jQuery like the following:
<table id="MatrixTable">
<tr>
<td id="321">
<a class="modal-dialog-link" href="Edit?matrixID=321" updatefunction="UpdateMatrix">
0
</a>
</td>
</tr>
</table>
$("table#MatrixTable td").mouseover(function () {
// doing something here...
});
B. How can I come back to the original '0' when mouseleave with jQuery like the following:
$("table#MatrixTable td").mouseleave(function () {
// doing something here...
});
Thanks.
Use jQuery.hover
$("table#MatrixTable #321").hover(function () {
$(this).html('<a class="modal-dialog-link" href="Edit?matrixID=321"'+
'updatefunction="UpdateMatrix">0</a>');
},function(){
$(this).text('0');
});
You can use hover to bind an event handler to the mouseenter and mouseleave events, and you can use wrap and unwrap to wrap the contents in an a element:
$("#321").hover(function() {
$(this).contents().wrap("<a>");
}, function() {
$(this).find("a").contents().unwrap();
});
Here's a working example. Inspect the DOM to see the changes as you hover over the element.
This seems like a very strange way to use a link though... why can't the link always be in the DOM?
It's kinda difficult to explain what I want to achieve (and feel free to modify the title if you can think of a better one), so I'll give you an example:
Street: First Lane
South side 28
City: Duckburg
Country: Disneyland
ZIP: 1234567890-XY
This is what I want the user to see. But I also want the user to be able to select only the right column, so he can copy-paste the contents of it elsewhere. If I do this with a table, the user can only select whole rows, and a copy-paste operation will copy row headers as well. If I do this with two separate containers next to each other, the labels get out of synch with the contents if some item has more than one line.
Can this be achieved somehow?
Yes. Try something like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Page Title</title>
<style type="text/css" media="screen">
#left_side { float: left; text-align: right;}
</style>
</head>
<body>
<div id="container">
<div id="left_side">
Street:<br><br>
City:<br>
Country:<br>
ZIP:
</div>
<div id="right_side">
First Lane<br>
South side 28<br>
Duckburg<br>
Disneyland<br>
1234567890-XY
</div>
</div>
</body>
</html>
Yes, it is possible.
Use YUI datatable. It works even with JQuery.
Although this sample use row selection you can use column selection
You can use any input format including JSON, HTML table, XML and text. No input field required. I use somenting like
App http://img74.imageshack.us/img74/1833/singled.gif
According to above, when i click (yes, mouse click) a single row, it will be highlighted (selected) and supported actions will be applied (Edit). Supported actions will be applied according to your business requirement
In your case, a HTML table, you set up according to (You can test it if you want):
First lets set up CSS and JavaScript
<!-- Combo-handled YUI CSS files: -->
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/combo?2.7.0/build/paginator/assets/skins/sam/paginator.css&2.7.0/build/datatable/assets/skins/sam/datatable.css">
<style type="text/css">
.center {text-align:center;}
</style>
<!-- Combo-handled YUI JS files: -->
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.7.0/build/yahoo-dom-event/yahoo-dom-event.js&2.7.0/build/connection/connection-min.js&2.7.0/build/element/element-min.js&2.7.0/build/paginator/paginator-min.js&2.7.0/build/datasource/datasource-min.js&2.7.0/build/datatable/datatable-min.js&2.7.0/build/json/json-min.js"></script>
Our body (generated on server side)
<body class="yui-skin-sam">
<div id="container">
<table id="source">
<thead>
<tr>
<th>AAA</th>
<th>BBB</th>
<th>CCC</th>
<th>HIDDEN</th>
</tr>
</thead>
<tbody>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>0</td>
</tr>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>1</td>
</tr>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td>2</td>
</tr>
</tbody>
</table>
</div>
<div id="actionContainer">
<a id="action" href="#">Edit row</a>
</div>
</body>
Now lets configure script after body (code commented)
<script type="text/javascript">
var settings = {
widgetList:{
reference:null,
datatable:{
columnSettings:[
// key attribute matches key attribute in dataSource fields attribute - see bellow
{key:"AAA", label:"A custom label"},
// if label is omitted, default to key value
// className customizes a class to apply to a column
{key:"BBB", className:"center"},
{key:"CCC"},
// i do not want to show id value, so i hide it through hidden attribute
{key:"HIDDEN", hidden:true},
// i want to generate a custom value regardless dataSource, so i set up a custom formatter function - see below
{key:"CUSTOM", label:"A custom value", formatter:customValue}
],
settings:{
selectionMode:"single"
}
}, // eof datatable
dataSource:{
// use $("#source")[0] whether you use JQuery (do not forget set up JQuery)
// source points to data that will populate our datatable
// in our case data will be retrieved from a HTML table
// see responseType bellow
source:YAHOO.util.Dom.get("source"),
settings:{
responseSchema:{
fields:[
// key attribute matches th content
{key:"AAA"},
{key:"BBB"},
{key:"CCC"},
{key:"HIDDEN"}],
// set up input
responseType:YAHOO.util.DataSource.TYPE_HTMLTABLE
}
}
}, // eof dataSource
create:function() {
this.reference = new YAHOO.widget.DataTable("container", this.datatable.columnSettings, new YAHOO.util.DataSource(this.dataSource.source, this.dataSource.settings), this.datatable.settings);
} // eof create
} // eof widgetList
}; // eof setting
// sets up custom value
function customValue(container, record, column, data) {
// container references a cell
container.innerHTML = record.getData("AAA") + " - " + record.getData("BBB") + " - " + record.getData("CCC") + " - " + record.getData("HIDDEN");
}
(function() {
// use $("#actionContainer").set("display", "none"); in JQuery
YAHOO.util.Dom.setStyle("actionContainer", "display", "none");
settings.widgetList.create();
// RIA applications
YAHOO.util.Event.addListener("action", "click", function(e) {
e.preventDefault();
var datatable = settings.widgetList.reference;
var recordArray = datatable.getRecordSet().getRecords();
for(var i = 0; i < recordArray.length; i++) {
if(datatable.isSelected(recordArray[i])) {
alert("You have selected id: " + recordArray[i].getData("HIDDEN") + "\nYou can use a JQuery dialog to collect data changes");
}
}
});
// rowClickEvent - use subscribe
settings.widgetList.reference.subscribe("rowClickEvent", function(args) {
// args.target is a Record instance
if(this.isSelected(args.target)) {
this.unselectRow(args.target);
YAHOO.util.Dom.setStyle("actionContainer", "display", "none");
} else {
this.unselectAllRows();
this.selectRow(args.target);
YAHOO.util.Dom.setStyle("actionContainer", "display", "block");
}
});
})();
</script>
</html>
Minimal changes are required if you use JSON, XML or text. Feel free to ask for them.
In order to use column selection use columnClickEvent instead.
regards,
Could you have all of the right hand column of your example in 1 cell somehow? That way it would be all selected together.
The row headers would stay aligned as long as the number of rows in each part of the address was always the same.