jQuery nested filter - asp.net

I'd like to have the first 6 columns of a GridView perform an action, but I need to highlight the entire row when it is clicked. The entire row highlighting is working, but I can't quite get the capturing of the first 6 columns. How do I capture the first 6 columns click in the following where the testing variable is located?:
$("#<%= JobStreamSelectedDealsGridView.ClientID %> tr").filter(function() {
return $('td', this).length && !$('table', this).length
})
.bind('click', function(e) {
if (_activeRow) _activeRow.removeClass('gridviewrow-highlighted');
_activeRow = $(this).addClass('gridviewrow-highlighted');
var testing = $('td:lt(6)', this);
});

You can do it like this:
var _activeRow;
$("#<%= JobStreamSelectedDealsGridView.ClientID %> tr")
.delegate('td:not(:has(table)):lt(6)', 'click', function(e) {
if (_activeRow) _activeRow.removeClass('gridviewrow-highlighted');
_activeRow = $(this).closest('tr').addClass('gridviewrow-highlighted');
});​
You can try it out here. I'm not sure about your parent-row-with-child-table exclusion, but I've replicated it here since I'm sure you had a reason :)
This uses .delegate() to reduce the number of event handlers, it attaches an event handler to each row, and when a <td> that's :lt(6) (less than 6th index, 0-based) gets clicked we go up to the nearest <tr> using .closest() and do the class manipulation there.

Try this. You are binding the click even to only the first 6 TD's.
$("#<%= JobStreamSelectedDealsGridView.ClientID %> tr").filter(function() {
return $('td', this).length && !$('table', this).length
})
find("td:eq(0), td:eq(1), td:eq(2), td:eq(3), td:eq(4), td:eq(5)").bind('click', function(e) {
if (_activeRow) _activeRow.removeClass('gridviewrow-highlighted');
_activeRow = $(this).addClass('gridviewrow-highlighted');
var testing = $(this);
});

Related

Dynamically control edit mode of dojo DataGrid column

I just started using dojo and just started to play around with it. Basically what I want do is that I have a table which has 2 columns A and B. The cells in Column B will either be locked or editable depending on the value of column A.
Is there a way to set the editable property at cell level and not on the column level as defined in the layout?
I tried using the formatter but can't get it to work properly.
You can override the grid function onCellDblClick - but this is version-specific code. If the dojo.version changes in your page, the grid Event.js may have other behaviors. The following snippet is taken from ... /dojox/grid/_Event.js from version 1.7.2.
If your editing is set to fire via doubleclicking a cell (default behavior), you may choose to simply ignore it with a well placed return in the following:
var customOnEditActivate = function(e){
// summary:
// Event fired when a cell is double-clicked.
// e: Event
// Decorated event object contains reference to grid, cell, and rowIndex
var event;
if(this._click.length > 1 && has('ie')){
event = this._click[1];
}else if(this._click.length > 1 && this._click[0].rowIndex != this._click[1].rowIndex){
event = this._click[0];
}else{
event = e;
}
////
// entrypoints of interest: event.cell & event.cellNode(.innerHTML)
// As example we could ignore editing mode if cell contains 'NON_EDITABLE'
if(cell.innerHTML.match("NON_EDITABLE"))
return;
//
////
this.focus.setFocusCell(event.cell, event.rowIndex);
this.onRowClick(event);
this.edit.setEditCell(event.cell, event.rowIndex);
this.onRowDblClick(e);
},
So whilst initializing your grid, set the config parameter onCellDblClick to the above function:
require(["dojox/grid/DataGrid"], function(DataGrid) {
var grid = new DataGrid({
onCellDblClick: customOnEditActivate
});
});
or
<div
data-dojo-type="dojox.grid.DataGrid"
data-dojo-props="onCellDblClick: customOnEditActivate"
></div>
You could override the
canEdit: function(inCell, inRowIndex)
method of the DataGrid. From that, you can get the item:
this.getItem(inRowIndex)
then work out if it should be editable or not, and return true/false.
I got the following to work (similar to Ed Jellard's suggestion):
<script type="dojo/require">
jsonRestStore : "dojox/data/JsonRestStore",
contentPane : "dijit/layout/ContentPane",
dataGrid : "dojox/grid/DataGrid"
</script>
<div dojoType="dijit.layout.ContentPane">
<script type="dojo/method">
configStore = new dojox.data.JsonRestStore
( { target : "/data/config",
idAttribute : "propertyName" } );
configStructure =
[ {field:'propertyName', name:'Property - Name',
width:20},
{field:'value', name:'Value',
editable:true},
{field:'guiConfigurable', name:'Property Type'},
{field:'description', name:'Description'}
];
</script>
</div>
<table data-dojo-type="dojox.grid.DataGrid"
store="configStore"
structure=configStructure>
<script type="dojo/method" event="canSort" args="sortInfo">
return false;
</script>
<script type="dojo/method" event="onApplyCellEdit" >
configStore.save();
</script>
<script type="dojo/method" event="canEdit" args="inCell, inRowIndex">
var gc = this.getItem(inRowIndex).guiConfigurable;
return gc == 'W' || gc == 'D';
</script>
<tbody/>
</table>

Select Row in WEBGRID

How can a select a Row of a WEBGRID after binding it so that row
will get highlighted(by mouse click on any row or cell of any row without the
use of check-box or option button as column)
1.)After selecting any row can I get the data value for that row?
2.) Can I move selection up and down by keyboard (up and down keyboard
button)?
3.) And after changing the index of selecting row(by mouse or by keyboard
up-down button) is rowselectedindexchaged or rowselectingindexchanging event
can be fired/handled
Thank you
There's a lot to this question, and there are lots of ways to implement it. Here's a rough sketch of how you could do this. I'm going to assume you're using JQuery as that will make this a lot easier.
To highlight a row or cell on click, attach click events to each:
$("tr").click(function() { $(this).css('background', 'yellow'); });
$("td").click(function() { $(this).css('background', 'lightblue'); });
Of course, you'll also need to un-highlight them, but we'll come to that in a moment.
To get data for a row (I assume you mean on the server, not the client), you'll have to do an AJAX call. It will be easiest to get the id of the row rather than passing the whole row back. Something like this inside the click events:
var row_id = $(this).closest("tr").find("input[type=hidden]").attr("value");
$.get("?row_id=" + row_id);
This assumes that you have added a hidden input to each row in your Webgrid with its row ID value.
In case you need to access the selected first row cell you can use this inside the click function:
var cellOne = this.cells[0].innerHTML ;
I also recommend that your click function should only be linked to a certain table (otherwise the selection will be enabled on all tr elements) and use a css class that is added and removed when selection changes.
$('#MainTable tr').click(function () {
$(this).addClass('select');
$('#MainTable tr').not(this).removeClass('select');
});
To move up and down, you can add a "keyup" event listener to the window and handle up/down. See here for more details: jQuery kepress detection on left, right arrows and space bar. You'll have to use Javascript to keep track of which row is currently selected so as to highlight/unhighlight as needed.
Finally, for the last question, you can trigger an AJAX call (or Javascript call) when the user clicks or arrow-keys to a different row. You'll already be keeping track of which row number has been selected, so you can just send that along with the event:
$.get("?event=row_selection_changed&row_id=" + row_id);
You can try this code:
<div id="AjaxWebGrid">
#grid.GetHtml(
htmlAttributes: new { id = "MainTable" },
tableStyle: "webGrid",
headerStyle: "header",
alternatingRowStyle: "alt",
selectedRowStyle: "select",
columns: grid.Columns(
grid.Column("SendedInDateTime", "SendDate", null, style: "SendDateTimeStyle"),
grid.Column("", header:"حذف", format:
#<text>
#Ajax.ActionLink("Delete", "Delete",
new { id = "", DelID = item.Id }, new AjaxOptions { UpdateTargetId = "AjaxWebGrid" },
new { #class = "button" })
</text>)
));
</div>
<script>
$(document).ready(function () {
$('#MainTable tr').click(function () {
$(this).addClass('select');
$('#MainTable tr').not(this).removeClass('select');
});
});
</script>
#grid.GetHtml(htmlAttributes: new { id="MainTable" }, .....);
<script type="text/javascript">
$(function ()
{
var tr = $('#MainTable').find('tr');
tr.bind('click', function (event)
{
$("tr").click(function () { $(this).css('background', 'yellow'); });
});
});
</script>

Jquery help needed for onbeforeunload event

I am using jquery onbeforeunload event in asp.net application.
If i write event as given below then its working fine and display confirm dialog box.
var vGlobal = true;
var sMessage = "Leaving the page will lost in unsaved data!";
[ Working ]
> window.onbeforeunload = function() {
> if (vGlobal == false) return
> sMessage; }
but its not working if i use bind method like as given below
[ Not working ]
$(window).bind("beforeunload", function(e) {
if (vGlobal == false)
return sMessage;
});
Anybody suggest me why its not working.Is there any difference between these two methods.
Code on aspx:
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
CLICK ON THIS LINK TO SEE RUNNING EXAMPLE
See the updated version
You need to bind all the events inside document ready event.
Apart from the fact that vGlobal is true and you are checking if (vGlobal == false), this smells like a $(document).ready() issue.
I.e. you should place the declaration inside a document.ready() handler as shown here:
$(document).ready(function(){
$(window).bind("beforeunload", function(e) {
if (vGlobal == false)
return sMessage;
});
});
There is no benefit in using jQuery to bind the event to the window - all you are doing is adding the overhead of having jQuery parse the window into a jQuery object, which you aren't even using.
Therefore, using:
window.onbeforeunload = handler;
Is preferable to using jQuery to bind this event.
You can still perform the binding inside of the document ready section:
$(document).ready(function () {
window.onbeforeunload = handler;
};

How to highlight a row in gridview?

My applications sends emails to users, with a hyperlink for an aspx page. There is a guid in the get string. The aspx page shows gridview with rows across multiple pages.
My requirement is when the link is clicked the user should be directed to appropriate page and the row with mapping to guid should be highlighted?
Canavar has a point, but for a simple thing, you can take the load of the RowDataBound method and perform the hightlight at the end of the rendering.
Let's imagine (cause you did not provided any information regarding it - BTW, please give us always the most detailed version of a question) :)
GridView had 30 rows displayed and we need to hightlight the Row ID 22.
follow this steps:
1 - Add an HiddenField with
<asp:HiddenField ID="rowID" CssClass="rowids" Value='<%# Eval("YourROWID") %>' />
2 - Now that we have the row, all we need is, when the DOM is ready, loop trough all rows and hightlight the one that has the same Value to the selectrow that you mention in a comment
Are you using jQuery?
var selectedRow = '<%= Request["selectrow"] %>';
$(document).ready(function(){
$(".rowids").each( function() { // Get and Loop through all class=rowids elements
if( $(this).value() == selectedRow) {
// we found it! lets find the TR and add the highlight class to it
$(this) // the INPUT ELEMENT
.parent() // the TD element
.parent() // the TR element
.addClass("highlight"); // Add the class
}
});
});
if not using jQuery (you should though, cause I almost sure that you will re use it else where to improve more part in your code)
var selectedRow = '<%= Request["selectrow"] %>';
var arr = document.getElementsByTagName("input");
for (i = 0; i < arr.length; i++) { // Loop through all input elements
if( arr[i].className == "rowids" && arr[i].defaultValue == selectedRow ) {
// it's a rowids element and the value is the one we are looking out
var tableRow = arr[i].parentNode.parentNode; // get it's TR element
tableRow.className = tableRow.className + ' hightlight'; // Add the class
break; // no need to loop through more, we already found the one we are looking for
}
}
REMEMBER to add this in a script before the BODY tag, so it will be called when all elements are rendered in the page (DOM ready trick)
You can use JQuery for that.
$("a").click(function(){
$(this).effect("highlight", {}, 3000);
})
it would be something that simple. Hope it helps.

ASP.NET, jQuery, dirty forms, and window.onbeforeunload

In my ASP.NET web app, I'm trying to create a universal way of warning users before navigating away from a form when they've made changes, using jQuery. Pretty standard stuff, but after a lot of searching I have yet to find a technique that works.
Here's what I have at this point:
addToPostBack = function(func) {
var old__doPostBack = __doPostBack;
if (typeof __doPostBack != 'function') {
__doPostBack = func;
} else {
__doPostBack = function() {
old__doPostBack();
func();
}
}
}
var isDirty = false;
$(document).ready(function() {
addToPostBack(function() {
alert("Postback detected.")
clearDirty();
});
$(':input').bind("change select keydown", setDirty);
window.onbeforeunload = function(e) {
var msg = "You have unsaved changes. "
if (isDirty == true) {
var e = e || window.event;
if (e) { e.returnValue = msg; }
return msg;
}
};
});
setDirty = function() {isDirty = true;}
clearDirty = function() {isDirty = false;}
This works as far as warning the user from navigating away. The problem is that I get the warning on every same-page postback. There are a number of things on my forms that might trigger a postback:
There are Save, Cancel, and Delete linkbuttons on the page
There might be other linkbuttons on the page that execute server-side functionality while staying on the same page
There might be other controls with autopostback=true that also have server-side functions attached to them, but which don't result in the user leaving the page.
None of these things should provoke a warning, because the user isn't leaving the page. My code tries to hijack addToPostBack (more details on that in this question) to clear the isDirty bit before posting back, but the problem is that in IE onbeforeunload fires before __doPostBack, apparently because IE fires onbeforeunload immediately when a link is clicked (as described here).
Of course, I could wire up each of these controls to clear the isDirty bit, but I'd prefer a solution that operates on the form level and that doesn't require that I touch every single control that might trigger a postback.
Does anyone have an approach that works in ASP.NET and that doesn't involve wiring up every control that might cause a postback?
I came across this post while Googling for a solution for doing the same thing in MVC. This solution, adapted from Herb's above, seems to work well. Since there's nothing MVC-specific about this, it should work just as well for PHP, Classic ASP, or any other kind of application that uses HTML and JQuery.
var isDirty = false;
$(document).ready(function () {
$(':input').bind("change select keydown", setDirty);
$('form').submit(clearDirty);
window.onbeforeunload = function (e) {
var msg = "You have unsaved changes. "
if (isDirty == true) {
var e = e || window.event;
if (e) { e.returnValue = msg; }
return msg;
}
};
});
setDirty = function () { isDirty = true; }
clearDirty = function () { isDirty = false; }
Interesting, but... why don't you do everything with jQuery?
var defaultSubmitControl = false;
var dirty = false;
$(document).ready(function( ) {
$('form').submit(function( ) { dirty = false });
$(window).unload(function( ) {
if ( dirty && confirm('Save?') ) {
__doPastBack(defaultSubmitControl || $('form :submit[id]').get(0).id, '');
}
});
});
···
dirty = true;
···
Now, if that still causes the same issue (unload triggering before submit), you could try a different event tree, so instead of calling __doPostBack directly you do...
setTimeout(function( ) {
__doPastBack(defaultSubmitControl || $('form :submit[id]').get(0).id, '');
}, 1); // I think using 0 (zero) works too
I haven't tried this and it's from the top of my head, but I think it could be a way to solve it.
You could always create an inherited page class that has a custom OnLoad / OnUnload method that adds in immediate execution JavaScript.
Then you don't have to handle it at a control specific level but rather the form / page level.
Got this to work by basically tracking the mouse position. Keep in mind you can still get positive values to your Y value (hence my < 50 line of code), but as long as your submit buttons are more than 100 pixels down you should be fine.
Here is the Javascript I added to track mouse changes and capture the onbeforeunload event:
<script language="JavaScript1.2">
<!--
// Detect if the browser is IE or not.
// If it is not IE, we assume that the browser is NS.
var IE = document.all?true:false
// If NS -- that is, !IE -- then set up for mouse capture
if (!IE) document.captureEvents(Event.MOUSEMOVE)
// Set-up to use getMouseXY function onMouseMove
document.onmousemove = getMouseXY;
// Temporary variables to hold mouse x-y pos.s
var tempX = 0
var tempY = 0
// Main function to retrieve mouse x-y pos.s
function getMouseXY(e) {
if (IE) { // grab the x-y pos.s if browser is IE
tempX = event.clientX + document.body.scrollLeft
tempY = event.clientY + document.body.scrollTop
} else { // grab the x-y pos.s if browser is NS
tempX = e.pageX
tempY = e.pageY
}
// catch possible negative values in NS4
if (tempX < 0){tempX = 0}
if (tempY < 0){tempY = 0}
// show the position values in the form named Show
// in the text fields named MouseX and MouseY
document.Show.MouseX.value = tempX
document.Show.MouseY.value = tempY
return true
}
//-->
</script>
<script type="text/javascript">
window.onbeforeunload = HandleOnClose;
function HandleOnClose(e) {
var posY = 0;
var elem = document.getElementsByName('MouseY');
if (elem[0]) {
posY = elem[0].value;
}
if (posY < 50) { // Your form "submit" buttons will hopefully be more than 100 pixels down due to movement
return "You have not selected an option, are you sure you want to close?";
}
}
</script>
Then just add the following form onto your page:
<form name="Show">
<input type="hidden" name="MouseX" value="0" size="4">
<input type="hidden" name="MouseY" value="0" style="display:block" size="0">
</form>
And that's it! It could use a little cleanup (remove the MouseX, etc), but this worked in my existing ASP.net 3.5 application and thought I would post to help anyone out. Works in IE 7 and Firefox 3.6, haven't tried Chrome yet.
i am looking after this too but what i have find so far is, a solution that uses all the html controls instead of asp.net web controls, have you think of that?
<script type="text/javascript">
$(document).ready(function () {
$("form").dirty_form();
$("#btnCancel").dirty_stopper();
});
</script>

Resources