Google maps inside an update panel - asp.net

I have a repeater that outputs javascript for a Google Map
var marker5450635326848240000000 = new google.maps.Marker({
position: new google.maps.LatLng(31.2272,-85.4072),
map: map,
title: '4/10/2014'
});
markers.push(marker5450635326848240000000);
I have the map plus a pulldown inside an updatepanel. When the user changes the pulldown the updatepanel updates everything, but the pins on the map do not change.
Here is the example: http://prod.windcreekhospitality.bkwld.onyxtek.com/Giving-Back/Good-on-the-Go.aspx
I know it is the update panel because when I take the panel out of the equation it works.
http://windcreekhospitality.com/Giving-Back/Good-on-the-Go
Where is the whole code for the ascx http://pastebin.com/FqX0PndG
This is an ascx control and it is build for use with Kentico CMS. This limits my choices.

I had a similar problem recently trying to integrate a captcha script inside of an UpdatePanel.
Script blocks inside of an UpdatePanel only get recognized by the browser on the initial page load. Due to the way UpdatePanels work, any new script tags won't be injected into the browser correctly for them to actually be executed.
One work-around will be to use the ScriptManager.RegisterStartupScript method to register the script block dynamically from code-behind. The ASP.NET's ajax library will then handle registering the javascript code correctly and calling it to execute.
If you pass an UpdatePanel control as the first paramter to RegisterStartupScript(), the code will be included in the rendering on the first page load, any full postbacks, and every partial postback if that UpdatePanel is being updated.
In code-behind, build the javascript as a string and then pass it to RegisterStartupScript. Example:
protected override void OnPreRender(EventArgs e)
{
var s = new StringBuilder();
s.Append(#"
var markers = [];
var currentWindow;
var myLatlng = new google.maps.LatLng(32.3617,-86.2792);
var mapOptions = {
zoom: 6,
center: myLatlng,
scrollwheel: false
};
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
$('#map-canvas').mouseleave(function(){
if(currentWindow)
currentWindow.close();
});
google.maps.event.addListener(map, 'mousedown', function() {
if(currentWindow)
currentWindow.close();
} );");
// TODO: manually do whatever that cms:CMSRepeater control would be done to generate the additional JS and append it to the StringBuilder.
ScriptManager.RegisterClientScriptBlock(EventsUpdatePanel, GetType(), "InitMap", s.ToString(), true);
base.OnPreRender(e);
}
Better would be to separate out your function that inits the map, move it to be OUTSIDE of the UpdatePanel, and pass it as arguments the data you want it to initialize. Have the code-behind generate JS that is just a call to that function with the data as arguments.

One way our team handle this issueis by adding the following
on the Webpart(here your Map) -> Envelope->Content before
<script type="text/javascript">
function MyFunction() {
......
}
MyFunction();
Sys.Application.add_load(MyFunction);
</script>
Also , bring the repeater outside the script tag(see your Pastbin code) and call the pageLoad method as described up.

Related

ASP GridView to be updated automatically when ModalDialog is closed

I have a gridView with search and filtering options, it is listing document from SharePoint Library, when i click on the Document name i added a Modal popup to display Documents properties page, if i update Document's title for example and select save, the item is updated but the gridview is still showing the old title, i need to press Search again in order to refresh the values.
the code i use for model popup is:
<script type="text/javascript">
function openModal(url) {
var options = SP.UI.$create_DialogOptions();
options.url = url;
options.dialogReturnValueCallback = Function.createDelegate(null, CloseCallback);
SP.UI.ModalDialog.showModalDialog(options);
}
// Dialog callback
function CloseCallback(result, target) {
if (result === SP.UI.DialogResult.OK) {
SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
}
}
</script>
what should i do to refresh and bid gridview data when the popup is closed?
on the click of save button, make a serverside call to rebind the gridview. i.e
$(document).ready(function(){
$('id_of_save_button').click(function(){
//ajax call of serverside method to rebind the grid.
});
});
However with asp.net these things become little easy if you use modalPopupExtender that ships with asp.net
Hi for handling sharepoint save event using javascript u can use this function
function PreSaveAction()
{
// write your gride view data bind code
}

How to get the id of Updatepanel which is about to start a postback

I need to get the id of the panel that is about to start a postback, so I have a generic way to block ui on this panel.
So far I have this function:
function BeginRequestHandler(sender, args) {
$('#' + args.get_updatePanelsToUpdate()[0]).block({ message: null });
}
attached like this:
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
this works pretty well to get the id if control that causes partial postback is inside update panel, but if it is outside (using a trigger), args.get_updatePanelsToUpdate() is always null
I've seen this answer, but it wont work forme because function is fired after partial postback is complete, I need it before..
Thank you
So here's what I did:
created 2 functions to block (on partial postback begin) and unblock (on partial postback end):
function BeginRequestHandler(sender, args) {
$('#' +sender._postBackSettings.panelsToUpdate[0].ReplaceAll('$', '_')).block({ message: 'loading...' });
}
function EndRequestHandler(sender, args) {
$('#' + sender._postBackSettings.panelsToUpdate[0].ReplaceAll('$', '_')).unblock();
}
Registered above functions on my page right after my script manager:
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
</script>
Some conditions:
I'm using jquery UI block plugin but you should use what better fits your needs.
You update panels should have ClientIDMode="AutoID" if your using .NET 4.0 +
I used the following helper function cause js doesn't make a real replace all and to deal with asp net autoID's:
String.prototype.ReplaceAll = function (stringToFind, stringToReplace) {
var temp = this;
var index = temp.indexOf(stringToFind);
while (index != -1) {
temp = temp.replace(stringToFind, stringToReplace);
index = temp.indexOf(stringToFind);
}
return temp;
}
If you just want to disable (or animate in some other way) the UpdatePanel, why not just use UpdatePanelAnimation? It provides you with the following hooks (not sure if that's the right word):
OnUpdating - Generic animation played as when any UpdatePanel begins
updating
OnUpdated - Generic animation played after the UpdatePanel
has finished updating (but only if the UpdatePanel was changed)

namespacing javascript in user control

I have created a jquery slider usercontrol in asp.net using jquery UI slider. The user control have some javascript functions to set the value of the slider when the textbox value changes in the main page. Everything works fine if I have only usercontrol. But if I have multiple user controls, I am not sure how to namespace the javascript so that it calls the function inside the specific user control.
Thanks,
Sridhar.
I would suggest object orienting your code - something like this (Obviously this is only pseudocode...)
function Slider(parentElement, id){
var element = ... // get / create your element here
// attach appropriate event listeners here...
element.onclick = function(){
//event handling code...
}
this.setValue = function(value){
// set value of element
}
this.getValue = function(){
//get value of element
}
}
var sliderA = new Slider(document.getElementById('anElement'));
var sliderB = new Slider(document.getElementById('anotherElement'));

How can I execute JavaScript from my code-behind after my UpdatePanel has finished loading its DOM elements?

I have an UpdatePanel with a repeater in it that is re-bound after a user adds an item to it via a modal popup.
When they click the button to add a new row to the repeater the code-behind looks something like this:
protected void lbtnAddOption_Click(object sender, EventArgs e)
{
SelectedOption = new Option()
{
Account = txtAddOptionAccountNumber.Text,
Margin = chkAddOptionMargin.Checked,
Symbol = txtAddOptionSymbol.Text,
Usymbol = txtAddOptionUsymbol.Text,
};
Presenter.OnAddOption(); // Insert the new item
RefreshOptions(); // Pull down and re-bind all the items
mpeAddOptionDialog.Hide(); // Hide the modal
// ... Make call to jQuery scrollTo() method here?
}
This works fine and the new row will show up quickly via the UpdatePanel.
However, there are often hundreds of rows and where the new one is added is based on the current sorting column used.
So, I wanted to take this as a chance to use the sweet jQuery ScrollTo plugin. I know that if I give it the ID of my overflowed container div and the ID of an element within it, it will smoothly scroll straight to the users newly added row.
However, there are two problems:
I need to find the appropriate row so I can snag the ClientID for it.
I need to execute the jQuery snippet from my code-behind that will cause my newly updated repeater to scroll to the right row.
I've solved #1. I have a reliable method that will produce the newly added row's ClientID.
However, problem #2 is proving to be tricky. I know I can just call ScriptManager.RegisterStartupScript() form my code-behind and it will execute the JavaScript on my page.
The problem I'm having is that it seems that it is executing that piece of JavaScript before (I'm guessing) the newly refreshed DOM elements have fully loaded. So, even though I am passing in the appropriate jQuery line to scroll to the element I want, it is erroring out for me because it can't find that element yet.
Here is the line I'm using at the end of the method I posted above:
string clientID = getClientIdOfNewRow();
ScriptManager.RegisterStartupScript(this, typeof(Page), "ScrollScript", String.Format("$(\"#optionContainer\").scrollTo(\"{0}\", 800);", clientID), true);
What do I need to do so I can ensure that this line of JavaScript isn't called until the page with the UpdatePanel is truly ready?
If the stuff you need to process is in the update panel, then you need to run your JS once that panel is loaded. I use add_endRequest for that. This below is hacked from something rather more complex. It runs once on document ready, but installs the "end ajax" handler which is triggered every time your update panel is updated. And by the time it fires, it's all there for you.
var prm = Sys.WebForms.PageRequestManager.getInstance();
jQuery(document).ready(function () {
prm.add_endRequest(EndRequestHandler);
});
function EndRequestHandler(sender, args) {
// do whatever you need to do with the stuff in the update panel.
}
Obviously you can inject that from code-behind if you want.
You can use the Sys.Application.load event which is raised after all scripts have been loaded and the objects in the application have been created and initialized.
So your code would be:
string clientID = getClientIdOfNewRow();
ScriptManager.RegisterStartupScript(this, typeof(Page)
,"ScrollScript"
,String.Format("Sys.Application.add_load(function(){{$(\"#optionContainer\").scrollTo(\"{0}\", 800);}});"
, clientID)
, true);

Jquery code on load not firing

I have the following JQuery code in a external JS file linked into a
usercontrol in .Net 1.1 webapp.
The usercontrol is a timesheet.
When the page loads it calls MonthChange and works fine in one page.
But now I want to load the timesheet/usercontrol into aother
webpage that pops up a in a new browser window for printing.
Problem is my MonthChange is not firing.
Any ideas why???
$(function() {
MonthChange();
//TestData();
$('[class^=TSGridTB]').blur(function() {
var day = GetDay($(this).attr('id'));
var date = GetRowDate(day);
var bgcolor = GetInputFieldColor(date, false);
$(this).css("background-color", bgcolor);
$(this).parent().css("background-color", bgcolor);
//CalcHours($(this).get(0));
});
$('[class^=TSGridTB]').focus(function() {
var day = GetDay($(this).attr('id'));
var date = GetRowDate(day);
var bgcolor = GetInputFieldColor(date, true);
$(this).css("background-color", bgcolor);
$(this).parent().css("background-color", bgcolor);
});
$('[id$=lstMonth]').change(function() {
MonthChange();
});
});
without seeing further code, ensure that the selector is correct for the control in the new page.
The problem may be that the DOM has changed for the new page/window and JQuery does not yet know about it.
The change event
fires when a control loses the input
focus and its value has been modified
since gaining focus.
You might want to use the live event:
Binds a handler to an event (like
click) for all current - and future -
matched element.
When you bind a "live" event it will
bind to all current and future
elements on the page (using event
delegation). For example if you bound
a live click to all "li" elements on
the page then added another li at a
later time - that click event would
continue to work for the new element
(this is not the case with bind which
must be re-bound on all new elements).
Did you make sure that the new web page has jQuery script includes?
ensure you're using:
$(document).ready(
);
around your entire code block. The $ alone often does not do the trick.

Resources