Is it possible to position ValidatorCalloutExtender dynamically? - c#

I have two ajax validator callout extenders that are programmed via VB.net.I am validating one textbox but I want the popup to appear next to a different textbox. How can I tell the ajax popup where to appear?
Dim custval As New CustomValidator
custval.ID = "ValidPage"
custval.ErrorMessage = "<font color=red>Please Enter a 'To' Date"
custval.SetFocusOnError = True
custval.ForeColor = Drawing.Color.Red
custval.EnableClientScript = True
custval.ControlToValidate = cell.Controls(18).ID
custval.ClientValidationFunction = "ClientValidate"
custval.Display = ValidatorDisplay.None
Dim custvalex As New AjaxControlToolkit.ValidatorCalloutExtender
custvalex.ID = "VCEcustval"
custvalex.TargetControlID = "ValidPage"
custvalex.HighlightCssClass = "validatorCalloutHighlight"
'---------------------------------------------------------------
Dim custval2 As New CustomValidator
custval2.ID = "ValidPage2"
custval2.ErrorMessage = "<font color=red>Please Enter a 'From' Date"
custval2.SetFocusOnError = True
custval2.ForeColor = Drawing.Color.Red
custval2.EnableClientScript = True
custval2.ControlToValidate = cell.Controls(23).ID
custval2.ClientValidationFunction = "ClientValidate2"
custval2.Display = ValidatorDisplay.None
Dim custvalex2 As New AjaxControlToolkit.ValidatorCalloutExtender
custvalex2.ID = "VCEcustval2"
custvalex2.TargetControlID = "ValidPage2"
custvalex2.HighlightCssClass = "validatorCalloutHighlight"
cell.Controls.Add(custval) '27
cell.Controls.Add(custvalex2) '28
cell.Controls.Add(custval2) '29
cell.Controls.Add(custvalex) '30
function ClientValidate(sender, args) {
// Get Both form fields
var hid = $get('<%=HiddenField1.ClientID%>');
var hid2 = $get('<%=HiddenField2.ClientID %>');
var hidval = hid.value;
var hid2val = hid2.value;
var txtdate1 = $get(hidval);
var txtdate2 = $get(hid2val);
// do you client side check to make sure they have something
if (txtdate1.value != '' && txtdate2.value == '') {
args.IsValid = false;
}
else {
args.IsValid = true;
}
}
function ClientValidate2(sender, args) {
// Get Both form fields
var hid = $get('<%=HiddenField1.ClientID%>');
var hid2 = $get('<%=HiddenField2.ClientID %>');
var hidval = hid.value;
var hid2val = hid2.value;
var txtdate1 = $get(hidval);
var txtdate2 = $get(hid2val);
// do you client side check to make sure they have something
if (txtdate2.value != '' && txtdate1.value == '') {
args.IsValid = false;
}
else {
args.IsValid = true;
}
}
I know that those two javascript functions can be separated. But how can I move the popup around?

You'll probably have to control the positioning of it via CSS or javascript. I don't know of a way to do it through the properties of the server control.
Here is a forum thread showing how to reposition the validator popup using the set_x and set_y javascript methods of the callout.

Related

id of $.find control is undefined

I'm trying to generate a control dynamicaly and after change another control. For example i have a button and a label, i want to change label's text using AJAX/JS/etc, without post/get queries. So i'm writing a code like this:
foreach (var pair in FailedMonitorings)
{
var server = (ServerEnum)pair.Key;
var tabPanel = new TabPanel { HeaderText = server.GetDescription() };
var updatePanel = new UpdatePanel();
var upChilds = updatePanel.ContentTemplateContainer.Controls;
var label = new Label { Text = "Hello from UP-" + tabPanel.HeaderText, ID = "lbl" + tabPanel.HeaderText};
upChilds.Add(label);
const string command = #"var ctrl = $.find(""{0}""); alert(ctrl.id); return false;";
var button = new Button {Text = "Button"};
upChilds.Add(button);
tabPanel.Controls.Add(updatePanel);
tbcErrors.Tabs.Add(tabPanel);
button.OnClientClick = string.Format(command, label.ClientID);
}
so generated html here:
for a start i just want to create a messagebox with id of control, but even this simple code doesn't work. Question is: why? And how to solve it?
Added: ctrl is not null
when command is
const string command = #"var ctrl = $.find(""{0}""); alert(((ctrl != null).toString() + ' ') + ctrl.id); return false;";
result is true undefined
I think it should be
const string command = #"var ctrl = $('#{0}')[0]; ctrl.innerText = 'Updated!'; return false;";
Why I say this is in jquery to select an element with an id you would use the same convention as a css selector which means you need to prefix the id with a '#' so $('#elementid') will select for a DOM element like <label id="elementid" /> what I would do is
foreach (var pair in FailedMonitorings)
{
var server = (ServerEnum)pair.Key;
var tabPanel = new TabPanel { HeaderText = server.GetDescription() };
var updatePanel = new UpdatePanel();
var upChilds = updatePanel.ContentTemplateContainer.Controls;
var label = new Label { Text = "Hello from UP-" + tabPanel.HeaderText, ID = "lbl" + tabPanel.HeaderText};
upChilds.Add(label);
const string command = #"updateText('{0}')";
var button = new Button {Text = "Button"};
upChilds.Add(button);
tabPanel.Controls.Add(updatePanel);
tbcErrors.Tabs.Add(tabPanel);
button.OnClientClick = string.Format(command, label.ClientID);
}
then in html
<script type="text/javascript">
function updateText(id){
var ctrl = $('#' + id);
ctrl.text('Updated text');
return false;
}
</script>
I prefer that the button call an updateText function as a posed to rendering all the code inline to the client. It makes the code easier to maintain without having to recompile server side. If you need to work with a dom element then you could use var ctrl = $('#' + id)[0]; this would return the first dom element found for the jquery selection once you have it then you can set the innerText to a value ctrl.innerText = 'Updated!';. I didn't do that in my answer because I just wanted to show how it could be done purely from jquery.
The code
const string command = #"var ctrl = $.find(""{0}""); alert(((ctrl != null).toString() + ' ') + ctrl.id); return false;";
will not work firstly because your jquery selector var ctrl = $.find(""{0}""); will not select the correct control on the client. It would probably render script something like
<button onclick="var ctrl = $.find("Ctrl$Label1");alert(((ctrl != null).toString() + ' ') + ctrl.id); return false;" />
which means that ctrl would not be null but an empty array as there is no dom element like Ctrl$Label1 and since arrays don't have a property of id, it would be undefined. what you are after is a '#' in front of the clientId. The second reason this still will return undefined is that even if you do have a valid selector. Is that the JQuery object returned doesn't have a property of id so you will still see undefined. So finally to get both the id and get the correct selector it would look like
const string command = #"var ctrl = $('#{0}')[0]; alert(ctrl.id); return false;
or if you need to set the text it would look like
const string command =# "var ctrl = $('#{0}')[0]; ctrl.innerText = 'Updated!; return false;

How to get values from dynamically generated controls in asp.net c#?

I know this is a well asked question and I found some marked as answers but those doesn't solve my problem. Please have a look at my codes..
Method to Display dynamic controls
private void ShowControlsByFormId()
{
List<FormControlsBO> list = new List<FormControlsBO>();
list = new FormControlsDA().FormControls_GetByFormId(Convert.ToInt32(ddlForm.SelectedValue.ToString()));
if (list.Count > 0)
{
for (int i = 0; i < list.Count; i++)
{
DynamicControl dynamicControl = CommonUtility.GenerateControl(list[i]);
pnlInput.Controls.Add(new LiteralControl("<tr><td>"));
pnlInput.Controls.Add(dynamicControl.GeneratedControlLiteral);
pnlInput.Controls.Add(new LiteralControl("</td><td></td><td>"));
pnlInput.Controls.Add(dynamicControl.GeneratedControl);
pnlInput.Controls.Add(new LiteralControl("</td><tr><br/><br/>"));
}
pnlAction.Visible = true;
}
else
{
pnlAction.Visible = false;
}
}
Method to Generate dynamic controls
public static DynamicControl GenerateControl(FormControlsBO bo)
{
DynamicControl dynamicControl = new DynamicControl();
Control control = new Control();
LiteralControl literal = new LiteralControl();
switch (bo.FieldType)
{
case "TextBox":
control = new TextBox();
control.ID = bo.FieldName;
literal.Text = bo.FieldLabel;
break;
case "RadioButton":
control = new RadioButton();
control.ID = bo.FieldName;
literal.Text = bo.FieldLabel;
break;
case "CheckBox":
control = new CheckBox();
control.ID = bo.FieldName;
literal.Text = bo.FieldLabel;
break;
case "DropDownList":
control = new DropDownList();
control.ID = bo.FieldName;
literal.Text = bo.FieldLabel;
break;
}
control.ClientIDMode = ClientIDMode.Static;
dynamicControl.GeneratedControl = control;
dynamicControl.GeneratedControlLiteral = literal;
return dynamicControl;
}
Method to Save data
private void FormRecords_Save()
{
List<FormControlsBO> list = new List<FormControlsBO>();
FormControlsBO bo = new FormControlsBO();
foreach (Control ctl in pnlInput.Controls)
{
CommonUtility.DataFiller(bo, ctl);
list.Add(bo);
}
Boolean result = false;
result = new FormControlsDA().FormRecords_Save(list);
if(result == true)
{
lblMessage.Text = "Form data saved successfully";
}
else
{
lblMessage.Text = "Form data not saved";
}
}
The problem is, when I debug the code, pnlInput.Controls shows Zero count. Please help !!
As I already answered here all dynamic controls should be reinitiated in Page's Init event, as viewstate manager values are set every request. You can check page's lifecycle.
So right now, when you do not create you control in init event, viewstates misses them while it is setting postback data, and when you do try to get values, they are equal to zeros.
Keep in mind, that you have to create the same control types with the same names.
If you have written the code to generate Dynamic Controls and if it is in the page load event use FindControl("IdofControl"); to retrive its value;
For Example,
TextBox txtInstance = (TextBox)FindControl("IdofControl");
string txtvalueinTextBox =txtInstance.Text;
Make sure that the controls are dynamically generated in all page reloads.If the controls generated on the postback is different the viewState may not restore back properly.

AutoComplete with context key in a Textbox based on two parameters?

Refer the Image, having 2 TextBox(tbxAttribute and tbxAttributeDesc).
Value will be loaded when page is loaded in tbxAttribute TextBox.In tbxAttributeDesc TextBox the end user will Fill that Data.
I have already Completed the Autocomplete Text in tbxAttributeDesc.
We are maintaining these Values in a table, Based up on the loaded tbxAttribute value their corresponding AttributeDesc will be highlight into tbxAttributeDesc Textbox
My Code be:
autoDesc = new AjaxControlToolkit.AutoCompleteExtender();
autoDesc.ID = "autoDesc" + i;
autoDesc.BehaviorID = "tbxAtribute" + i;
autoDesc.ServicePath = "itemvaluemas.asmx";
autoDesc.ServiceMethod = "GetAttributeDesc";
autoDesc.TargetControlID = tbxAttributeDesc.ID;
autoDesc.MinimumPrefixLength = 1;
autoDesc.CompletionInterval = 10;
autoDesc.FirstRowSelected = true;
autoDesc.CompletionSetCount = 30;
autoDesc.UseContextKey = true;
and also used Javscript Concept.
Refer the Below Image:
Here i need to pass condition as tbxAtribute and their Corresponding tbxAtributeDesc, based up on that tbxAbbr Value need to be highlight..
if i use ContextKey then how i pass these two textbox value in a context key..
If you have any idea please help to solve this problem.
Use ContextKey property to pass the value of textbox into GetAutoCompleteValues function.
txtbox1.Attributes.Add("onchange", "$find('BehaviourIDOftbxAttributeDesc').set_contextKey(tbxAttribute.value);");
For more information check the below links:
AJAX C# AutoCompleteExtender contextKey
http://arrao4u.wordpress.com/2010/01/14/autocomplete-extender-with-context-key/
This is the Solution which i found.
I use JavaScript:
function SetContextAbbr(formatid, itemValue, behaveid) {
var autoComplete1 = $find(behaveid);
var target = autoComplete1.get_element();
var txtformatid = document.getElementById(formatid);
var txtitemValue = document.getElementById(itemValue);
var contextkeydata = txtformatid.value + "-" + txtitemValue.value;
autoComplete1.set_contextKey(contextkeydata);
}
Use Function as
public string[] GetItemabbr(string prefixText, int count, string contextKey)
{
string[] splitvalue = contextKey.Split('-');
//code here
}
In WebService
autoabbr = new AjaxControlToolkit.AutoCompleteExtender();
autoabbr.ID = "autoabbr" + i;
autoabbr.BehaviorID = "autoabbrbehave" + i;
autoabbr.ServicePath ="itemvaluemas.asmx";
autoabbr.ServiceMethod = "GetItemabbr";
autoabbr.TargetControlID = txtItemAbbrValue.ID;
autoabbr.MinimumPrefixLength = 1;
autoabbr.CompletionInterval = 10;
autoabbr.FirstRowSelected = true;
autoabbr.CompletionListCssClass = "completionList";
autoabbr.CompletionListHighlightedItemCssClass = "itemHighlighted";
autoabbr.CompletionListItemCssClass = "listItem";
autoabbr.CompletionSetCount = 30;
autoabbr.UseContextKey = true;

LookUpEdit DisplayFormat FormatString

I'am having simple problem with DevExpress LookUpEdit DisplayFormat. I want to achieve results in lookUpEdit like:
Document type (.doc)
Document type (.docx)
const string defaultExtensionsList = "doc;docx;xlsx;xls;pdf;txt";
//...
var column = new LookUpColumnInfo("Column", "Extensions")
{
Visible = true,
//FormatType = FormatType.Custom,
//FormatString ="Document type (*.{0})",
Alignment = HorzAlignment.Near
};
ExtensionsLookup.Properties.DisplayFormat.FormatType = FormatType.Custom;
ExtensionsLookup.Properties.DisplayFormat.FormatString = "Document type (*.{0})";
ExtensionsLookup.Properties.EditFormat.FormatType = FormatType.Custom;
ExtensionsLookup.Properties.EditFormat.FormatString = "Document type (*.{0})";
ExtensionsLookup.Properties.Columns.Add(column);
var bindingList = defaultExtensionsList.Split(';').ToList();
ExtensionsLookup.Properties.DataSource = bindingList;
You can use the following trick (RepositoryItemLookUpEdit.GetNotInListValue event):
const string defaultExtensionsList = "doc;docx;xlsx;xls;pdf;txt";
//...
var columnID = new LookUpColumnInfo("Column", "IDs") { Visible = false };
var columnToDisplay = new LookUpColumnInfo("Display", "Extensions");
lookUpEdit.Properties.Columns.AddRange(new LookUpColumnInfo[] { columnID, columnToDisplay });
lookUpEdit.Properties.ValueMember = "Column";
lookUpEdit.Properties.DisplayMember = "Display";
lookUpEdit.Properties.TextEditStyle = TextEditStyles.DisableTextEditor;
lookUpEdit.Properties.GetNotInListValue += OnGetNotInListValue;
var bindingList = defaultExtensionsList.Split(';').ToList();
lookUpEdit.Properties.DataSource = bindingList;
//...
void OnGetNotInListValue(object sender, GetNotInListValueEventArgs e) {
if(e.FieldName == "Display")
e.Value = string.Format("Document type (*.{0})",
((IList<string>)lookUpEdit.Properties.DataSource)[e.RecordIndex]);
}
If I remember correctly, LookUpEdit doesn't support this functionality.
I would simply build a List with values "Document type (.docx)", "Documentype (.xy)" and bind it to the control.
Something like
var types = defaultExtensionsList.Split(';').Select(s => "DocumentType (*." + s + ")").ToList();

Javascript tabs: call event onclick

I got some code I need to change. it is build by others, and not very neat...
There is a javascript tabcontrol, containing 4 tabs, which contains gridviews.
All the 4 gridviews are build during the load of the page, but I want them to load, when you activate the tabs (as it is possible to watch the side, while you don't need the specific gridviews to see)
So, my question is: how to call an event (that loads the gridview) from an javascript tab?
how the tabs are generated: (generated code, I know, horrible)
var obj = 0;
var oid = 0;
var otb = 0;
var myTabs = new Array();
var myTabitems = new Array();
var myTabitem = new Array();
var myTabContent = new Array();
var myLists = new Array();
function showTabContent(tab)
{
tb = tab.obj;
id = tab.nr;
if (myTabs[tb].oid != -1)
{
myTabs[tb].myTabContent[myTabs[tb].oid].style.display = 'none';
myTabs[tb].myTabitem[myTabs[tb].oid].className -= " active";
}
myTabs[tb].myTabContent[id].style.display = 'block';
myTabs[tb].myTabitem[id].className += " active";
myTabs[tb].oid = id;
}
function boTabs()
{
var myBlocks = new Array();
myBlocks = document.getElementsByTagName("div");
var stopit = myBlocks.length;
for (var g = 0; g < stopit; g++)
{
if (myBlocks[g].className == "tabs")
{
myTabs.push(myBlocks[g]);
}
}
var stopit2 = myTabs.length;
for (var i = 0; i < stopit2; i++)
{
myTabs[i].myLists = myTabs[i].getElementsByTagName("ul");
if (myTabs[i].myLists[0].className == "tabs")
{
myTabs[i].myTabitems = myTabs[i].myLists[0].getElementsByTagName("li");
}
var stopit3 = myTabs[i].myTabitems.length;
myTabs[i].obj = i;
myTabs[i].myTabitem = new Array();
myTabs[i].myTabContent = new Array();
for (var j = 0; j < stopit3; j++)
{
myTabs[i].myTabitem.push(myTabs[i].myTabitems[j]);
myTabs[i].myTabitem[j].nr = j; myTabs[i].myTabitem[j].obj = i;
myTabs[i].myTabitem[j].onclick = function() { showTabContent(this); };
}
var myTabDivs = myTabs[i].getElementsByTagName("div");
for (var j = 0; j < myTabDivs.length; j++)
{
if (myTabDivs[j].className == "tabcontent")
{
myTabs[i].myTabContent.push(myTabDivs[j]);
}
}
myTabs[i].myTabitem[0].className += " active";
myTabs[i].myTabContent[0].style.display = 'block';
myTabs[i].oid = 0;
myTabDivs = null;
}
myBlocks = null;
}
onload = boTabs;
I would change it entirely to use JQuery Tabs and JQuery AJAX to load the grids
If you want a JS solution, you have to build the gridview table yourself using JS code... If you want the server to do the work, you need an UpdatePanel, and make use of the client _doPostBack method. If you like this approach, the Ajax Control Toolkit tab container can be configured to postback to the server whenever the tab changes, which you can wrap this control with an update panel, and it looks like everything is being done with JS code. Alternatively, you can also use a web service that binds a gridview and returns the HTML too... not tried that yet, but seen it done.
HTH, if you let me know what option you prefer, I could update accordingly.
I now got the tabcontrol made by JQuery and CSS.
at this moment all 4 gridviews are bound at Page_Load, but, as it takes time to run te sproc's behind the gridview, it takes a few seconds. Therefore I want to load them on tabclick... The UpdatePanel seems the best way...
JQuery:
$(document).ready(function()
{
//When page loads...
$(".tab_content").hide(); //Hide all content
$("ul.tabs li:first").addClass("active").show(); //Activate first tab
$(".tab_content:first").show(); //Show first tab content
//On Click Event
$("ul.tabs li").click(function()
{
$("ul.tabs li").removeClass("active"); //Remove any "active" class
$(this).addClass("active"); //Add "active" class to selected tab
$(".tab_content").hide(); //Hide all tab content
var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
$(activeTab).fadeIn(); //Fade in the active ID content
return false;
});
});

Categories

Resources