I've got a web page that uses an UpdatePanel and validation within.
Because of requirements specified within, I have to display a custom model when validation fails and so far, I've only been able to do this by overriding the Page_ClientValidate client side function:
function Page_ClientValidate(validationGroup) {
Page_InvalidControlToBeFocused = null;
if (typeof(Page_Validators) == "undefined") {
return true;
}
var i;
for (i = 0; i < Page_Validators.length; i++) {
ValidatorValidate(Page_Validators[i], validationGroup, null);
}
ValidatorUpdateIsValid();
ValidationSummaryOnSubmit(validationGroup);
Page_BlockSubmit = !Page_IsValid;
if(!Page_IsValid)
{
displayError();
}
return Page_IsValid;
}
This works great, but I've noticed that when using it within an UpdatePanel, as soon as the UpdatePanel generates new content, it seems the ScriptResource.axd's containing the original Page_ClientValidate is downloaded again, thus overriding my override (if that makes any sense).
Now, it displays the errors beside the fields, but doesn't call my displayError function.
Any suggestions?
I've thought about possibly writing something to monitor the error span's to see if they become visible, but not sure if that's overkill at the moment.
Thanks
Gavin
Are you using $(document).ready(...)?
if so, try to use the pageLoad() of the client side
http://encosia.com/document-ready-and-pageload-are-not-the-same/
Related
I need to set the background color of one of the buttons in the form's ribbon. This isn't supported through Ribbon Workbench, so I have written following javascripts to achieve the same:
function setOpportunityRibbonsAppearance() {
var submitToForeCastButton = parent.document.getElementById("opportunity|NoRelationship|Form|sfw.opportunity.Button1.Button");
if (submitToForeCastButton != null) {
submitToForeCastButton.style.backgroundColor = "lightyellow";
}
}
I have registered this scripts in Form Load event. However the issue is that, I always get parent.document.getElementById as null only.
Surprisingly, I am able to see the control while running the parent.document.getElementById statement in the browser's console, and can also change the styling attributes.
Can anyone please suggest what could be wrong here?
P.S. - I understand document.getElementById is not recommended to use in CRM, however, I am left with no other choice while trying to change the appearance of some of the buttons.
Any help on this, will be much appreciated.
You could upload an icon with a yellow background, to keep everything supported. You won't see text on yellow but it might work for you. Easy and standard.
To keep it unsupported and ugly, you could just keep on trying until you make it, setInterval allows for a function to be repeated:
function setOpportunityRibbonsAppearance() {
var submitToForeCastButton = null;
var interval = setInterval(function(){
submitToForeCastButton = parent.document.getElementById("opportunity|NoRelationship|Form|sfw.opportunity.Button1.Button");
if(submitToForeCastButton != null) {
submitToForeCastButton.style.backgroundColor = "lightyellow";
clearInterval(interval);
}
}, 500); // Every 500ms. Adjust as needed, not too fast or browser will choke.
}
Its probably because your script is running before the page is fully loaded.
Try adding a delay to the to the function Put a Delay in Javascript
I'm writing an rgl widget within the htmlwidgets framework so that rgl scenes can be used for output in Shiny apps. Things are basically working (though it's still rough around the edges; see the rglwidget package on http://R-forge.r-project.org ), but it's not nearly as responsive as the native Javascript controls that are already in rgl.
I suspect the problem is the round trip to the server.
Sometimes this will be unavoidable: if you want to make big changes to a scene, you may want to do a lot of calculations in R. But in other cases (the ones covered by the native controls), there's no need for R to be involved, everything can be done in Javascript.
I don't want to duplicate all the work that has gone into writing the Shiny input controls, but I'd like to use them. So my question is:
Is there a way to tell a Shiny input to call a Javascript function when it is changed, not to send its value to the server to be used in a Shiny output?
The answer to my question is "Yes"! It's actually fairly straightforward, at least if the control uses the htmlwidgets framework.
Warning: I'm not very experienced in Javascript, so this may not be very good Javascript style. Please let me know if so, and I'll improve it.
Here's the idea: If I have a Shiny sliderInput() control with inputId = "foo", then my own Javascript code can get it using window["foo"], and can set an "onchange" event handler on it. When that event handler is triggered, I can read the "value" property, and send it to my controls.
If I don't use the reactive inputs from the slider, I don't get the delay from going to the server.
Here's my current renderValue function for the widget:
renderValue: function(el, x, instance) {
var applyVals = function() {
/* We might be running before the scene exists. If so, it
will have to apply our initial value. */
var scene = window[x.sceneId].rglinstance;
if (typeof scene !== "undefined") {
scene.applyControls(x.controls);
instance.initialized = true;
} else {
instance.controls = x.controls;
instance.initialized = false;
}
};
el.rglcontroller = instance;
if (x.respondTo !== null) {
var control = window[x.respondTo];
if (typeof control !== "undefined") {
var self = this, i, oldhandler = control.onchange;
control.onchange = function() {
for (i=0; i<x.controls.length; i++) {
x.controls[i].value = control.value;
}
if (oldhandler !== null)
oldhandler.call(this);
applyVals();
};
control.onchange();
}
}
applyVals();
},
I am using ajaxtoolkit modalpopupextender to display a processing message. It's working fine on a typical postback (button click, etc).
However, I am calling a postback in javascript and the progress message isn't showing UNLESS I add an "alert" in the javascript.
Here's my javascript:
function getOrder() {
beginRequest('', '')
var hid = document.getElementById("ctl00_ContentPlaceHolder_hid");
//alert(hid.value);
__doPostBack("SaveOrder", hid.value);
endRequest('', '')
}
I obviously don't want to have an "alert" so does anyone have a solution or ran into this?
Here's the other pience of javascript used relating to this (typical stuff):
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequest);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);
var mdlCtl = document.getElementById('ctl00_hfModalCtlID').value;
function beginRequest(sender, args){
$find(mdlCtl).show();
}
function endRequest(sender, args) {
$find(mdlCtl).hide();
}
I'm stumped on why the "alert" makes a difference in the javascript that shows the processing message...?
Thoughts? Ideas?
Is there a way to determine from JavaScript if a page contains a scriptmanager, an updatepanel or if the __doPostBack is called from an update panel or is a partialpostback?
When one update panel is called, then there are two functions that trigger from javascript side. Inside this functions you can also get the Ids of the panel that trigger this update. If there is a full post back outside of an update panel, then you need to capture the submit of the form.
Here are the code that triggered when an update panel is going to upadte, together with the functions that show the update panel ids that make the trigger.
<script>
if(window.Sys && Sys.WebForms && Sys.WebForms.PageRequestManager)
{
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
}
else
{
// no ScriptManager found
}
function InitializeRequest(sender, args)
{
// get the array of update panels id
var UpdPanelsIds = args.get_updatePanelsToUpdate();
// get the Post ID
args.get_postBackElement().id;
}
function EndRequest(sender, args) {
}
</script>
'Dan Davies Brackett' Correct describe how you can know if the ScriptManager exist.
If I understand correctly, there are two questions here:
(1) how do I tell in JavaScript whether a ScriptManager exists on a page?
If the server-side page contains a ScriptManager, there will be a PageRequestManager available on the client. You can discover whether it exists with:
var haveScriptManager = window.Sys && Sys.WebForms && Sys.WebForms.PageRequestManager;
(2) how do I tell whether __doPostBack is synchronous?
Once you have a handle to the local PageRequestManager, you can hook the event that fires before every postback and check whether it's synchronous or asynchronous. Again, the documentation for the PageRequestManager will give you all the details of how to do that.
Emit the scriptManager clientID to some clientside javascript, then look for it on the page (document.getElementById(emittedClientID)
You can rename __doPostBack with... __NewDoPostBack = __doPostBack, then create a new function such as...
__doPostBack = function(whatever arguments __NewDoPostBack takes){
alert("We're doing a post back");
__NewDoPostBack(whatever arguments __NewDoPostBack takes)
}
In .NET 2.0, I have several client side validators ala the .NET validator controls. These run fine when I click a button...until I add my own javascript function to this button. Instead of running in addtion to the validators, it seems to prevent them from running at all.
To be clear, the validator controls are basic required field validators, and here is the javascript I added:
<script language="javascript">
function yaya()
{
var chkAmount = document.frmSearchFor.txtCheckAmount.value;
var amtApplied = document.frmSearchFor.lblAmountApplied.value;
if (amtApplied < chkAmount)
{
return confirm('Continue?');
}
}
</script>
And it's tied to the button like this...
OnClientClick="return yaya();
those are probably not the ID's being rendered to your page. Try this:
function yaya()
{
var checkAmount = parseFloat(document.getElementById("<%=txtCheckAmount.ClientID %>").value);
var amoutApplied = parseFloat(document.getElementById("<%=lblAmountApplied.ClientID %>").text);
if (amoutApplied < checkAmount)
{
return confirm('Continue?');
}
}
And try attaching it like this:
OnClientClick="javascript:yaya();";
Client-side validation is done via javascript just like your client click. When you specify the client-side event, I'm guessing there's nowhere for the validation code to attach. You may need to modify either the validation code to call your function, or your function to call the validation code. Probably the latter is easier. Instead of assigning OnClientClick at design time, add a client script that stores the current click handler function, creates a function that runs your code and then runs the stored handler function, and attaches that new function as the click handler.
<script>
var baseHandler = myElement.onclick;
myElement.onClick = function() {
// run your code here
baseHandler();
}
</script>
issue is that you are specifying a return in your OnClientClick attribute. when the page renders, it comes out like this
<input ... onclick="return yaya();WebForm_DoPostBackWithOptions...
after yaya completes, the onclick function concludes and I believe it's shutting down any further action that would normally happen before the form is submitted. it's kind of ugly but you can get around this by only having a return when your function evaluates to false:
OnClientClick="if (!yaya()) { return false; }"
for this to work you should also include return true; at the end of your function in case the conditions for the if check are not met.
you may also be having issues with references to elements as Hunter mentions but you're not providing your markup to verify that.