passing dynamically created ASP.NET controls to Javascript - javascript

I'm dynamically generating a textbox and a dropdownlist in my ASP.NET web app table row, I want to change value of textbox based on dropdownlist selectedindex using javascript, but I don't know how to pass these dynamically created controls to my Javascript function.
TextBox t = new TextBox();
tc.Controls.Add(t);
tr.Cells.Add(tc);
tc = new TableCell();
DropDownList ddl = new DropDownList();
ddl.Attributes.Add("onChange", "return OnFoodChange(this," + t + ");");
tc.Controls.Add(ddl);
I pass 'this' instead of my combobox, and it works fine, but textbox is not detected in my following javascript function:
function OnFoodChange(myCmb,myTxt) {
try{
var q = document.getElementById('<%= HFFoodPrice.ClientID %>').value.toString();
var q2 = q.split(';');
alert(myCmb.selectedIndex.toString());
alert(document.getElementById(myTxt.value));
for (var j = 0; j < q2.length; j++) {
if (q2[j] != '') {
var q3 = q2[j].split(',');
{
}
}
}
}
catch(err)
{
alert(err.message);
}
}
what is the correct way of passing dynamically created controls to a javascript function? should I set controls ID in my codebehind?

In C#:
ddl.Attributes.Add("onChange", "return OnFoodChange(this," + t.ClientID + ");");
in Javascript, try this:
alert(document.getElementById(myTxt).value);

Related

Column sum of multiple columns of dynamic gridview using Javascript

I have a Dynamic asp Gridview with all columns as template feild TextBox. The columns of the Gridview are also dynamic and column count may vary everytime.
Please find code below
public void FillPoDetails()
{
DataTable dt = new DataTable();
dt = pmdata.createdatatable(int.Parse(Session["OurStyleid"].ToString()), int.Parse(Session["PoPackid"].ToString()));
GenerateTable(dt.Columns.Count, dt.Rows.Count,dt);
foreach (DataColumn col in dt.Columns)
{
//Declare the bound field and allocate memory for the bound field.
TemplateField bfield = new TemplateField();
//Initalize the DataField value.
bfield.HeaderTemplate = new ArtWebApp.Controls.GridViewTemplate(ListItemType.Header, col.ColumnName);
//Initialize the HeaderText field value.
bfield.ItemTemplate = new ArtWebApp.Controls.GridViewTemplate(ListItemType.Item, col.ColumnName);
//Add the newly created bound field to the GridView.
GrdDynamic.Columns.Add(bfield);
}
GrdDynamic.DataSource = dt;
GrdDynamic.DataBind();
}
public GridViewTemplate(ListItemType type, string colname)
{
//Stores the template type.
_templateType = type;
//Stores the column name.
_columnName = colname;
}
void ITemplate.InstantiateIn(System.Web.UI.Control container)
{
switch (_templateType)
{
case ListItemType.Header:
//Creates a new label control and add it to the container.
Label lbl = new Label();
//Allocates the new label object.
lbl.Text = _columnName;
lbl.CssClass = "Headerclass";
//Assigns the name of the column in the lable.
container.Controls.Add(lbl);
//Adds the newly created label control to the container.
break;
case ListItemType.Item:
//Creates a new text box control and add it to the container.
TextBox tb1 = new TextBox();
//Allocates the new text box object.
tb1.DataBinding += new EventHandler(tb1_DataBinding);
//Attaches the data binding event.
tb1.Columns =6;
//Creates a column with size 4.
// tb1.Width = System.Web.UI.WebControls.Unit.Percentage(100);
tb1.Width = 100;
tb1.Wrap = true;
tb1.ID = "txt_" + _columnName;
if(_columnName== "ColorTotal")
{
tb1.CssClass = "ColorTotal";
}
else if (_columnName == "Color")
{
tb1.CssClass = "Color";
}
else
{
tb1.CssClass = "txtCalQty";
tb1.Attributes.Add("onkeypress", "return isNumberKey(event,this)");
tb1.Attributes.Add("onkeyup", "sumofQty(this)");
}
container.Controls.Add(tb1);
//Adds the newly created textbox to the container.
break;
}
}
And inorder to get the row total I had added a Javascript function on keydown event and its working clearly
//calculate the sum of qty on keypress
function sumofQty(objText) {
var cell = objText.parentNode;
var row = cell.parentNode;
var sum = 0;
var textboxs = row.getElementsByClassName("txtCalQty");
for (var i = 0; i < textboxs.length; i++)
{
sum += parseFloat(textboxs[i].value);
}
var textboxtotalqtys = row.getElementsByClassName("ColorTotal");
textboxtotalqtys[0].value = sum.toString();
}
And the result is Like below
can anyone please help me in finding out the sum of each columns(all same cssclass).and display it in the Sizetotal row because I am not able to loop through columns
I would give every textbox a row id and a column id through html5 data attributes. and in javascript (jQuery) filter the textboxes through column id.
example:
..
var sum = 0;
$( "input[data-column-id='" + selectedColumnId + "']" ).each(function( index )
{
sum += parseFloat($( this ).val() );
});
..
By the way, use jQuery. its amazing.
Not sure about your requirement but this may help you, After binding data to grid, once again loop through the column list
GrdDynamic.DataSource = dt;
GrdDynamic.DataBind();
int rowIndex=2;
GrdDynamic.FooterRow.Cells[1].Text = "Total";
GrdDynamic.FooterRow.Cells[1].HorizontalAlign = HorizontalAlign.Right;
foreach (DataColumn col in dt.Columns)
{
decimal total = dt.AsEnumerable().Sum(row => row.Field<decimal>(col.Caption));
GrdDynamic.FooterRow.Cells[rowIndex++].Text = total.ToString("N2");
}
There is a very simple way.
Add Footer and Label to each Column, Then do calculations from database side best is use LINQ and Group by, find footer Label Controls for each column and Bind values to those Footer's Label Control, in this way your UI will have less load.
See here for code:
.ASPX Page in Grid:
<asp:TemplateField HeaderText="Total">
<ItemTemplate>
<asp:Literal ID="ltrlTotal" Text='<%#Eval("Total") %>' runat="server"> </asp:Literal> // For Sub Total
</ItemTemplate>
<FooterTemplate>
<strong><asp:Literal ID="ltrlGrandTotal" runat="server"> // This is Grand Total
</asp:Literal></strong>
</FooterTemplate>
</asp:TemplateField>
C# Code:
var searchResult = soService.SearchResult(companyId);
var grandTotal = searchResult.Select(so => so.Total).Sum();
searchResult.All(aa => aa.GrandTotal == grandTotal);
gridSo.DataSource = searchResult;
gridSo.DataBind();
if (searchResult.Count > 0)
{
Literal ltrlGrandTotal = gridSo.FooterRow.FindControl("ltrlGrandTotal") as Literal;
if (ltrlGrandTotal != null)
ltrlGrandTotal.Text = string.Format("Grand Total : $ {0}", grandTotal);
}

Findcontrol for label in gridview using javascript

I have a gridview which has some templatefield. At cell5 i have a label which is the input for database. but not all the labels in all the rows contains the value. its based on the click event of an editTemplateField. I have vb.net code for accessing that label inside the gridview. but i want to get it by javascript. following is the sample vb.net code and javascript that i have tried so far.
For Each i as gridViewRow in gridview.Rows
Dim lnk as linkbutton = CType(i.FindControl("del"),LinkButton)
If lnk.ForeColor = Drawing.Color.Red
pid = CType(gridview.Rows(i).FindControl("lblposid"), Label).Text
End If
Next
javascript:
for (var i = 0; i < grid.rows.length-1; i++) {
if(grid.rows[i].cells[1].style.color == "red")
pid = grid.rows[i].cells[5].innerHTML;
}
vb.net works . but javascript is not working. i dont know how to make it in javascript.Thanks in advance]
Note: The template field's visible is "False" also.
I found my own solution now.
for (var i = 1; i < grid.rows.length; i++)
{
var links = grid.rows[i].getElementsByTagName("a");
if(links[1].style.color=="red")
{
var spanlist = grid.rows[i].getElementsByTagName("span");
pid=spanlist[1].innerHTML;
links[1].style.color="blue";
}
}

Gridview Footer row textbox in JavaScript

I have been accessing the rows of Gridview quite easily using javascript.
But when I try to add a new row and then try to access, then the code is not working.
Is there a way by which I can access the footer row text box?
Below is my code which works well when edit mode text boxes are to be accessed. Please donot post any link.
function OnSelectIndexChange() {
var drpdwn = document.getElementById("ddlSelectUnderwriterCond");
var drpdwnValue = drpdwn.options[drpdwn.selectedIndex].text;
var gridview = document.getElementById("<%= StandardUndewritingGrid.ClientID %>");
for (var i = 1; i <= gridview.rows.length; i++) {
var labels = gridview.rows[i].cells[0].getElementsByTagName("input")[0].value;
var txtbx = gridview.rows[i].cells[0].children[0];
if (drpdwnValue != '-- Select --')
txtbx.value = labels + '<^>' + drpdwnValue + '<^>';
}
}
I have just figured out a way of accessing the footer row and code is working fine so I am posting as it might help someone as well:
var flabels = document.getElementById('<%=((TextBox)gridname.FooterRow.FindControl("controlname")).ClientID %>');
if (flabels != null) {
}
It works by simple logic:
var grid = document.getElementById('<%= GridviewName.ClientID %>');
var FooterTextBoxName = grid.getElementsbyTagName('FooterTextBoxName');

Fill Array with div elements populated dynamically in codebehind. C#, javascript

I have a report populated as a table with a stringbuilder from the codebehind. The first TD of every row is a checkbox, the id of each checkbox is assigned dynamically:
sb.Append("<td><input type='checkbox' id='chkSelectAll_" + i + "' name='chk_" + i + "' onclick='JavaScript: chkAll_click(this);' /> </td>"
The aspx page uses a master page and
<asp:Content><div id='divMain'></div></asp:Content>
format other than a form to populate. The problem I am running in to is that I am having trouble finding all the elements (or any actually) of the div to work with. Here is the javascript I have been given. (Team project at work, I was just assigned 1 task on the project so changing anything is not an option.)
function divBatchBuild_click() {
debugger
var form = document.forms[0];
var visitList = '';
for (i = 0; i < form.elements.length; i++) {
if (form.elements[i].type == 'checkbox') {
//alert(form.elements[i].id.toString());
if (form.elements[i].checked == true &&
form.elements[i].id != 'chkSelectAll') {
var y = form.elements[i].id;
//alert('id=' + y[1].toString());
visitList = visitList + y[i].toString() + '|';
}
}
}
}
Apparently this worked on a previous project, but when used with this report the process never goes inside the if statement. Any help on what is going wrong is appreciated.
I think you want to first get the div, then get the elements in the div with the checkbox tagname. Something like:
var div = document.getElementById('divMain');
var elements = div.getElementsByTagName('checkbox');
for (i = 0; i < elements.length; i++) {

Confirm Delete pop up with Record Count

General Info:
Aspx page holds an Ascx User control. Inside the User control, the Repeater is contained inside a View, contained inside a Multiview.
Asp.Net 2.0 framework / C#
Details:
I have a repeater (inside an ascx user control) that shows records, and the first column is a checkbox. If checked, that row will be deleted.
OUtside the repeater, I have a button that will deleted all rows that are checked.
Everything works fine, but have been asked to add a pop up "confirm delete" message that includes the number of records that will be deleted if the user clicks "Ok" on the pop up.
Something like:
"You are about to delete 8 records".
Currently my button looks like this:
<asp:Button ID="btnDeleteAllRecords" runat="server" Text="Delete all Checked Records" Onclick="btnDeleteAllRecords_Click" OnClientClick="javascript:GetCbCount();" />
I have this javascript code block:
<script type="text/javascript">
function GetCbCount()
{
var cb = document.getElementById("rptrVoicemail").getElementsByTageName("input");
var cbCount;
for(i = 0; i < cb.lenght; i++)
{
if(cb[i].type == "checkbox")
{
if(cb[i].checked)
{
cbCount = cbCount + 1;
}
}
}
return confirm('You are about to delete' + cbCount + 'records.');
}
</script>
When I click my button I'm getting:
Error: 'document.getElementById(...)' is null or not an object
on this line:
var cb = document.getElementById("rptrVoicemail").getElementsByTageName("input");
Why is the JS not seeing my repeater? Is it because it's buried inside a MultiView? How can the JS be corrected so that the pop up will show the record count in the message?
UPDATE:
I changed the script to:
function GetCbCount(){
var inpt = document.getElementById("vmDiv");
var checkboxes = inpt.getElementsByTagName("input");
var cbCount;
for(i = 0; i<checkboxes.lenght;i++){
if (checkboxes[i].type == "checkbox" && checkboxes[i].checked){
cbCount = cbCount + 1;
}
}
return confirm('You are about to delete ' + cbCount + ' Voicemails.');
}
This should work:
document.getElementById('<%= rptrVoicemail.ClientID %>').getElementsByTageName("input");
Another approach is this little script that returns the ClientID. You could add it even to an included JS-file.
function GetClientId(strid)
{
var count=document.forms[ 0 ].length ;
var i = 0 ;
var eleName;
for (i = 0 ; i < count ; i++ )
{
eleName = document.forms [ 0 ].elements[ i ].id;
pos=eleName.indexOf( strid ) ;
if(pos >= 0) break;
}
return eleName;
}
Found here.
If you are using a master page or nesting controls (inside ascx, view, etc.) the framework will change the IDs that are rendered with elements.
If you do a "View Source" or use FireBug, you might see that rptrVoicemail became something like ctl00_ContentPlaceHolder1_someUserControl_ctl00_multiViewID_ctl28_rptrVoicemail.
You can use getElementById('<%= rptrVoicemail.ClientID %>') to get at the ID of the element as it would be rendered on the client.
Edit: To help debug, do something like this... you get the point.
var rptr = document.getElementById('<%= rptrVoicemail.ClientID %>');
rptr.borderColor = 'pink'; // draw a border to check it's the right element

Categories