I need to know the event which triggers when a devexpress grid is loaded, or when I move from one page to other.
I need to add on that event some code that adds a div element to a column from the grid.
Right now I have added to
$(document).ready(function () {
var node = document.createElement("div");
var y = document.getElementsByClassName('cssForColumn dxgv');
for (var item in y)
{
var aNode = $(y[item]);
aNode.wrapInner("<div class='documentColumn'></div>");
}
and it is working ok, but only when the grid is loaded initially.
I have tried like this:
$(".gvPartners_DXMainTable").load(function () {
alert("Handler for .change() called.");
});
with:
window.onload = function () {
alert("test");
};
document.getElementById("gvPartners_DXMainTable").onchange = function () {
alert("hello");
};
but I did not manage to make it work properly
This is the grid:
You may want to check the ClientSide Events of the ASPxGridView
Basically you have to use the Init
<dx:ASPxGridView ..............>
<ClientSideEvents Init="function(s, e) {
//Do your work here
}" />
</dx:ASPxGridView>
Related
I Have two pages, Pages A and Pages B, in Pages A i have button which one will redirect to Pages B, then i try to back to Page A using button from browser.
Please your suggestion, how i can disable my button in Page A for not redirect again to Pages B.
OK. If you want to disable the browser's back button feature, then you can try the below JavaScript: Put it in the head tag of the Sign Up page
<script type="text/javascript">
function noBack() { window.history.forward() }
noBack();
window.onload = noBack;
window.onpageshow = function (evt) { if (evt.persisted) noBack() }
window.onunload = function () { void (0) }
</script>
Note: This will only block the feature of browser's back button but if you manually go back to the Sign Up page writing in the address bar, this then will not work.
One more thing, as you are using Session, you can integrate it with the JavaScript as follows:
<script type="text/javascript">
var someVar = "Hello";
//var someVar = <%=this.Session["UserId"]%>; //Keeping the session value in JavaScript variable
function noBack() {
if (someVar == "Hello") { //You can use - if (someVar != null)
window.history.forward()
}
}
noBack();
window.onload = noBack;
window.onpageshow = function (evt) { if (evt.persisted) noBack() }
window.onunload = function () { void (0) }
</script>
I have a click event bound to the following ko function:
self.select = function (entity, event) {
var ctrlPressed = false;
if (event.ctrlKey) { ctrlPressed = true; }
if (!ctrlPressed) {
manager.deselectAll();
this.selected(true);
} else {
this.selected() ? this.selected(false) : this.selected(true);
}
}
It is bound like so:
data-bind="click: select, event: { dblclick: function(){alert('test');}}"
This currently works except that it fires "select" twice when you double click, which I do not want. I tried following the advice in this SO question, but when I create the singleClick() function, I get an error that "ctrlKey is not a function of undefined". So it's not passing the event properly. Further more, the doubleClick() function in the other answer there doesn't work at all. It gives an error on the "handler.call" part saying handler is not defined.
So, how can I successfully call my ko select function on singleClick but NOT on doubleclick?
I don't think this is really a knockout issue. You have at least these two options:
1. Implement some custom logic that prevents processing if a single click has started processing already
2. Prevent the double-click function altogether. JQuery has this handy handler:
$(selector).on("dblclick", function(e){
e.preventDefault(); //cancel system double-click event
});
So I technically got it to work. Here is my new singleClick function
ko.bindingHandlers.singleClick = {
init: function (element, valueAccessor, c, viewModel) {
var handler = valueAccessor(),
delay = 400,
clickTimeout = false;
$(element).click(function (event) {
if (clickTimeout !== false) {
clearTimeout(clickTimeout);
clickTimeout = false;
} else {
clickTimeout = setTimeout(function () {
clickTimeout = false;
handler(viewModel, event);
}, delay);
}
});
}
};
This passes the viewModel and event to the handler so I can still modify observables and capture ctrlKey pressed.
The binding:
data-bind="singleClick: select, event: { dblclick: function(){alert('test');}}"
The problem is that now, obviously, single clicking an item has a delay while it waits to see if it's a double click. This is an inherent and unsolvable issue, I believe, so though this technically answers my question, I will consider a completely different route (ie, no double-clicking at all in my interface)
I have a button which calls stored procedure and binds gridview.
I found a code on stackoverflow for top alert bar like this:
function topBar(message) {
var alert = $('<div id="alert">' + message + '</div>');
$(document.body).append(alert);
var $alert = $('#alert');
if ($alert.length) {
var alerttimer = window.setTimeout(function () {
$alert.trigger('click');
}, 10000);
$alert.animate({ height: $alert.css('line-height') || '50px' }, 500).click(function () {
window.clearTimeout(alerttimer);
$alert.animate({ height: '0' }, 200);
});
}
}
Then in my button I try to call this function like this:
Dim script As String = String.Format("topBar({0});", Server.HtmlEncode("Successfully Inserted"))
Response.Write(script) 'Or even like this
ClientScript.RegisterStartupScript(Page.GetType(), "topBar", script, True)
But it simply does not work.
Can you guide me in right direction?
I always sort this type of problems with supplying a Boolean Property whether javascript should fire a piece of script or not. For example :
public bool IsDone { get; set; }
Sorry that the code is in C#
This is a property on code behind file. When I need to fire the javascript method, I simply make this true.
What I do on the aspx page is as follows :
<script>
if(<%= IsDone.ToString().ToLower() %>) {
alert("Done!");
}
</script>
I have an ASP.NET FormView within an updatepanel. I'm auto-saving the form by setting AutoPostBack=true for each of the items within the FormView.
This means the user can click a few elements in quick succession and fire off a few async postbacks almost simultaneously.
The issue I have is that the user is able to keep scrolling down the form while the async postbacks are not yet complete. The browser always scrolls back to the position it was in at the first postback.
Page.MaintainScrollPositionOnPostback is set to False.
I've tried all sorts of things in ajax and jquery with:
pageLoad
add_initializeRequest
add_endRequest
document.ready
etc..
but I always only seem to be able to access the scroll Y as it was on the first postback.
Is there any way to retrieve the current scroll Y when the postback completes, so I can stop the scrolling occurring? Or perhaps is it possible to disable the scrolling behaviour?
Thanks!
Update
Thanks to #chprpipr, I was able to get this to work. Here's my abbreviated solution:
var FormScrollerProto = function () {
var Me = this;
this.lastScrollPos = 0;
var myLogger;
this.Setup = function (logger) {
myLogger = logger;
// Bind a function to the window
$(window).bind("scroll", function () {
// Record the scroll position
Me.lastScrollPos = Me.GetScrollTop();
myLogger.Log("last: " + Me.lastScrollPos);
});
}
this.ScrollForm = function () {
// Apply the last scroll position
$(window).scrollTop(Me.lastScrollPos);
}
// Call this in pageRequestManager.EndRequest
this.EndRequestHandler = function (args) {
myLogger.Log(args.get_error());
if (args.get_error() == undefined) {
Me.ScrollForm();
}
}
this.GetScrollTop = function () {
return Me.FilterResults(
window.pageYOffset ? window.pageYOffset : 0,
document.documentElement ? document.documentElement.scrollTop : 0,
document.body ? document.body.scrollTop : 0
);
}
this.FilterResults = function (n_win, n_docel, n_body) {
var n_result = n_win ? n_win : 0;
if (n_docel && (!n_result || (n_result > n_docel)))
n_result = n_docel;
return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
}
}
Main page:
...snip...
var logger;
var FormScroller;
// Hook up Application event handlers.
var app = Sys.Application;
// app.add_load(ApplicationLoad); - use pageLoad instead
app.add_init(ApplicationInit);
// app.add_disposing(ApplicationDisposing);
// app.add_unload(ApplicationUnload);
// Application event handlers for component developers.
function ApplicationInit(sender) {
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (!prm.get_isInAsyncPostBack()) {
prm.add_initializeRequest(InitializeRequest);
prm.add_beginRequest(BeginRequest);
prm.add_pageLoading(PageLoading);
prm.add_pageLoaded(PageLoaded);
prm.add_endRequest(EndRequest);
}
// Set up components
logger = new LoggerProto();
logger.Init(true);
logger.Log("APP:: Application init.");
FormScroller = new FormScrollerProto();
}
function InitializeRequest(sender, args) {
logger.Log("PRM:: Initializing async request.");
FormScroller.Setup(logger);
}
...snip...
function EndRequest(sender, args) {
logger.Log("PRM:: End of async request.");
maintainScroll(sender, args);
// Display any errors
processErrors(args);
}
...snip...
function maintainScroll(sender, args) {
logger.Log("maintain: " + winScrollTop);
FormScroller.EndRequestHandler(args);
}
I also tried calling the EndRequestHandler (had to remove the args.error check) to see if it reduced flicker when scrolling but it doesn't. It's worth noting that the perfect solution would be to stop the browser trying to scroll at all - right now there is a momentary jitter which would not be acceptable in apps with a large user base.
(The scroll top code is not mine - found it on the web.)
(Here's a helpful MSDN page for the clientside lifecycle: http://msdn.microsoft.com/en-us/library/bb386417.aspx)
Update 7 March:
I just found an extremely simple way to do this:
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(beginRequest);
function beginRequest()
{
prm._scrollPosition = null;
}
</script>
You could bind a function that logs the current scroll position and then reapplies it after each endRequest. It might go something like this:
// Wrap everything up for tidiness' sake
var FormHandlerProto = function() {
var Me = this;
this.lastScrollPos = 0;
this.SetupForm = function() {
// Bind a function to the form's scroll container
$("#ContainerId").bind("scroll", function() {
// Record the scroll position
Me.lastScrollPos = $(this).scrollTop();
});
}
this.ScrollForm = function() {
// Apply the last scroll position
$("#ContainerId").scrollTop(Me.lastScrollPos);
}
this.EndRequestHandler = function(sender, args) {
if (args.get_error() != undefined)
Me.ScrollForm();
}
}
}
var FormHandler = new FormHandlerProto();
FormHandler.Setup(); // This assumes your scroll container doesn't get updated on postback. If it does, you'll want to call it in the EndRequestHandler.
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(FormHandler.EndRequestHandler);
Simply put the Timer control within the content template.
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="5000" OnTick="Timer1_Tick">
</asp:Timer>
<asp:ImageButton ID="ImageButton1" runat="server" Height="350" Width="700" />
</ContentTemplate>
</asp:UpdatePanel>
Scenario: I have a standard dropdown list and when the value in that dropdownlist changes I want to update another dropdownlist that exists in a tinyMCE control.
Currently it does what I want when I open the page (i.e. the first time)...
function changeParent() {
}
tinymce.create('tinymce.plugins.MoePlugin', {
createControl: function(n, cm) {
switch (n) {
case 'mylistbox':
var mlb = cm.createListBox('mylistbox', {
title: 'Inserts',
onselect: function(v) {
tinyMCE.execCommand("mceInsertContent",false,v);
}
});
<% foreach (var insert in (ViewData["Inserts"] as List<String>)) { %> // This is .NET
yourobject = '<%= insert %>'; // This is JS AND .NET
mlb.add(yourobject, yourobject); // This is JavaScript
<% } %>
// Return the new listbox instance
return mlb;
}
return null;
}
});
<%= Html.DropDownList(Model.Record[184].ModelEntity.ModelEntityId.ToString(), ViewData["Containers"] as SelectList, new { onchange = "changeParent(); return false;" })%>
I am thinking the way to accomplish this (in the ChangeParentFunction) is to call a controller action to get a new list, then grab the 'mylistbox' object and reassign it, but am unsure how to put it all together.
As far as updating the TinyMCE listbox goes, you can try using a tinymce.ui.NativeListBox instead of the standard tinymce.ui.ListBox. You can do this by setting the last argument to cm.createListBox to tinymce.ui.NativeListBox. This way, you'll have a regular old <select> that you can update as you normally would.
The downside is that it looks like you'll need to manually hook up your own onchange listener since NativeListBox maintains its own list of items internally.
EDIT:
I played around a bit with this last night and here's what I've come up with.
First, here's how to use a native list box and wire up our own onChange handler, the TinyMCE way:
// Create a NativeListBox so we can easily modify the contents of the list.
var mlb = cm.createListBox('mylistbox', {
title: 'Inserts'
}, tinymce.ui.NativeListBox);
// Set our own change handler.
mlb.onPostRender.add(function(t) {
tinymce.dom.Event.add(t.id, 'change', function(e) {
var v = e.target.options[e.target.selectedIndex].value;
tinyMCE.activeEditor.execCommand("mceInsertContent", false, v);
e.target.selectedIndex = 0;
});
});
As far as updating the list box at runtime, your idea of calling a controller action to get the new items is sound; I'm not familiar with ASP.NET, so I can't really help you there.
The ID of the <select> that TinyMCE creates takes the form editorId_controlId, where in your case controlId is "mylistbox". Firebug in Firefox is the easiest way to find the ID of the <select> :)
Here's the test button I added to my page to check if the above code was working:
<script type="text/javascript">
function doFoo() {
// Change "myEditor" below to the ID of your TinyMCE instance.
var insertsElem = document.getElementById("myEditor_mylistbox");
insertsElem.options.length = 1; // Remove all but the first option.
var optElem = document.createElement("option");
optElem.value = "1";
optElem.text = "Foo";
insertsElem.add(optElem, null);
optElem = document.createElement("option");
optElem.value = "2";
optElem.text = "Bar";
insertsElem.add(optElem, null);
}
</script>
<button onclick="doFoo();">FOO</button>
Hope this helps, or at least gets you started.
Step 1 - Provide a JsonResult in your controller
public JsonResult GetInserts(int containerId)
{
//some code to get list of inserts here
List<string> somedata = doSomeStuff();
return Json(somedata);
}
Step 2 - Create javascript function to get Json results
function getInserts() {
var params = {};
params.containerId = $("#184").val();
$.getJSON("GetInserts", params, updateInserts);
};
updateInserts = function(data) {
var insertsElem = document.getElementById("183_mylistbox");
insertsElem.options.length = 1; // Remove all but the first option.
var optElem = document.createElement("option");
for (var item in data) {
optElem = document.createElement("option");
optElem.value = item;
optElem.text = data[item];
try {
insertsElem.add(optElem, null); // standards compliant browsers
}
catch(ex) {
insertsElem.add(optElem, item+1); // IE only (second paramater is the items position in the list)
}
}
};
Step 3 - Create NativeListBox (code above provided by ZoogieZork above)
var mlb = cm.createListBox('mylistbox', {
title: 'Inserts'
}, tinymce.ui.NativeListBox);
// Set our own change handler.
mlb.onPostRender.add(function(t) {
tinymce.dom.Event.add(t.id, 'change', function(e) {
var v = e.target.options[e.target.selectedIndex].value;
tinyMCE.activeEditor.execCommand("mceInsertContent", false, v);
e.target.selectedIndex = 0;
});
});
//populate inserts on listbox create
getInserts();