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>
Related
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 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>
I need to run a javascript function when the update panel is loaded completely(I want to scroll), and not on initial page load.
Please suggest.
Thanks
This is the way to get the end Event after the update.
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(EndRequest);
function EndRequest(sender, args) {
}
</script>
Untested
<script type="text/javascript">
var app = Sys.Application;
app.add_init(ApplicationInit);
function ApplicationInit(sender) {
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (!prm.get_isInAsyncPostBack())
{
prm.add_pageLoaded(PageLoaded);
}
}
function PageLoaded(sender, args) {
//Do something
}
</script>
If you are using AJAX then the only way i have found yet to give an alert to a user on return to the Asynchronous post back is to add an “end request” handler to the PageRequestManager.
In this way you can tell the request manager to run a javascript function on returning from a Asynchronous post back event of AJAX.
Code for doing this is :
function load()
{
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
}
where “EndRequestHandler” will be the name of your javascript function you want to call.
Call the above function in Onload event of tag:
<body onload=”load()”>
function EndRequestHandler()
{
alert(“You record has been saved successfully”);
}
Now If you want to give a different message based on your logic in server side code (code behind) then you can use a server side Hidden Field:
<input id=”hdnValue” type=”hidden” runat=”server” value=”" />
Set its value in server side code on Asychronous Post Back:
Protected Sub btn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCreateSample.Click
If condition Then
hdnValue.value = “do this”
Else
hdnValue.value = “do that”
End If
End Sub
Now you can check the value of this Hidden Field in your Client Side EndRequestHandler function and give a different alert to user based on its value:
function EndRequestHandler()
{
if (document.getElementById(‘<%= hdnValue.ClientID %>’).value == “do this”)
{
alert(“You record has been saved successfully”);
}
else
{
alert(“There is an error”);
}
}
you can use below code with if jquery is used
This is to show saved message and hide that message after 5 seconds after update panel is updated
function pageLoad() {
window.Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
}
function EndRequestHandler()
{
window.setTimeout(function () {
var label = window.$get('<%= lblMsg.ClientID%>');
if (label != null) { label.style.display = 'none'; }
}, 5000);
}
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();
I have an ASP.NET code-behind page linking several checkboxes to JavaScript methods. I want to make only one JavaScript method to handle them all since they are the same logic, how would I do this?
Code behind page load:
checkBoxShowPrices.Attributes.Add("onclick", "return checkBoxShowPrices_click(event);");
checkBoxShowInventory.Attributes.Add("onclick", "return checkBoxShowInventory_click(event);");
ASPX page JavaScript; obviously they all do the same thing for their assigned checkbox, but I'm thinking this can be reduced to one method:
function checkBoxShowPrices_click(e) {
if (_hasChanged) {
confirm(
'All changes will be lost. Do you wish to continue?',
function(arg) {
if (arg.toUpperCase() == 'YES') {
var checkBox = document.getElementById('<%=checkBoxShowPrices.UniqueID%
>');
checkBox.checked = !checkBox.checked;
eval("<%=base.GetPostBackEventReference(checkBoxShowPrices)%>");
_hasChanged = false;
}
});
return false;
} else {
eval("<%=base.GetPostBackEventReference(checkBoxShowPrices)%>");
}
}
function checkBoxShowInventory_click(e) {
if (_hasChanged) {
confirm(
'All changes will be lost. Do you wish to continue?',
function(arg) {
if (arg.toUpperCase() == 'YES') {
var checkBox = document.getElementById('<%
=checkBoxShowInventory.UniqueID%>');
checkBox.checked = !checkBox.checked;
eval("<%=base.GetPostBackEventReference(checkBoxShowInventory)%>");
_hasChanged = false;
}
});
return false;
} else {
eval("<%=base.GetPostBackEventReference(checkBoxShowInventory)%>");
}
}
Add to the event the checkbox that is raising it:
checkBoxShoPrices.Attributes.Add("onclick", "return checkBox_click(this, event);");
Afterwards in the function you declare it like this:
function checkBoxShowPrices_click(checkbox, e){ ...}
and you have in checkbox the instance you need
You can always write a function that returns a function:
function genF(x, y) {
return function(z) { return x+y*z; };
};
var f1 = genF(1,2);
var f2 = genF(2,3);
f1(5);
f2(5);
That might help in your case, I think. (Your code-paste is hard to read..)