Asp.net dynamic gridview with dropdownlists - javascript

I have a dynamic (allows addition of rows on the fly) an ASP gridview that has a dropdownlist in one of its columns. I would like to take an action enable/disable the textbox in the column after depending on the selection in the dropdownlist during data entry.
Any help will be highly appreciated.

You can do this easily with jQuery. With a bit of modification, you can get it working exactly as you want it to.
First, add the following to your <head> tag:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$(".ddlClass").change(function () {
var txt = $(this).closest("tr").find(".txtClass");
if ($(this).val() == 0) {
txt.css("background", "#cccccc");
txt.attr("disabled", "disabled");
}
else {
txt.css("background", "#ffffff");
txt.attr("disabled","");
}
});
});
Next, create your gridview and add template columns for your textbox and dropdown list. In the code below, notice that the dropdown list has been given a class "ddlClass" and the textbox has been given a class "txtClass". You can change these as you see fit.
<asp:gridview runat="server" ID="gvw" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="field1" />
<asp:BoundField DataField="field2" />
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:TextBox runat="server" ID="txtName" CssClass="txtClass"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<select class="ddlClass">
<option value="1">Enabled</option>
<option value="0">Disabled</option>
</select>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:gridview>
The .ready function attaches a click event to each dropdownlist with the class "ddlClass". When changed, the code will find the textbox with the class "txtClass" in the same row as the dropdownlist and then enable/disable accordingly.

Well you can use Javascript if you are familiar with that. I recommend using JQuery since its a query language for transversing through the DOM.
But if you are not familiar with Javascript then I recommend adding a SelectionChangedEvent on your DropDownList and then in the code behind for your page in the SelectionChangedEvent handler:
Cast the sender object to a DropDownList and then get the parent of that object which would be the GridViewRow.
With that GridViewRow you can use the FindControl method to get a reference to the TextBox in the same row and then you can enable it or disable it.
If you dont like the page refresh (post-back) everytime they change a selection in your dropdownlist then wrap your grid in an UpdatePanel.
Let me know if you are having a hard time with this and I'll post code to 1 of the above solutions. Just let me know which one you are most comfortable with.

Related

How to pass Javascript value to label server side

I have a gridview that contains two(2) ASPxComboBox the value of the second Combo box is base on the value of the first combo box. DevExpress demos and sample are a bit complicated and time consuming so I think of a workaround that when the selected item of combo box is exchange the value will store in a label. And I will get the value of label to store in dropdown. But I don't know how to pass the value of label in server side. Any help would be much appreciated. Thank you!
Here's my code.
FrontEnd
<asp:Label ID="LblProduct" runat="server" Text="Label"></asp:Label>
<dx:ASPxGridView ID="ASPxGridView2" OnRowDataBound="ASPxGridView2_RowDataBound" ClientInstanceName="GridV" runat="server" AutoGenerateColumns="False" DataSourceID="forprod" KeyFieldName = "ppdtl_no">
<columns>
<dx:GridViewDataTextColumn FieldName="fld_product" Name="Dd_product" ShowInCustomizationForm="true" VisibleIndex="3">
<SettingsHeaderFilter>
<DateRangePickerSettings EditFormatString="" />
</SettingsHeaderFilter>
<EditItemTemplate>
<dx:ASPxComboBox ID="ASPxComboBoxProduct" runat="server" DataSourceID="pp_prod" TextField="pp_ppname" ValueField="pp_ppcode">
<ClientSideEvents SelectedIndexChanged="function(s, e) { OnProductChanged(s); }"></ClientSideEvents>
</dx:ASPxComboBox>
</EditItemTemplate>
</dx:GridViewDataTextColumn>
<dx:GridViewDataComboBoxColumn FieldName="fld_type" Name="dd_type" ShowInCustomizationForm="true" VisibleIndex="4">
<SettingsHeaderFilter>
<DateRangePickerSettings EditFormatString="" />
</SettingsHeaderFilter>
<EditItemTemplate>
<dx:ASPxComboBox ID="ASPxComboBoxType" runat="server" DataSourceID="pp_type" TextField="pp_codetype" ValueField="pp_codetype">
</dx:ASPxComboBox>
</EditItemTemplate>
</dx:GridViewDataComboBoxColumn>
</columns>
</ASPxGridView>
JavaScript
function OnProductChanged(s, e) {
var selected_index = s.lastSuccessValue;
var aa = document.getElementById('LblProduct').innerText = selected_index;
}
onload = OnProductChanged;
You need to use the ClientID property of any element you run at server level in your selector. To achieve this, you have to write the JavaScript inside the file with your label, and then use <%= LblProduct.ClientID %>.
<script type="text/javascript">
document.getElementById('<%= LblProduct.ClientID %>');
</script>
Look at your project during runtime with Inspect - you will see the ID after compilation is not LblProduct, but something similar to ProjectName_PageName_ContentPlaceHolderName_LblProduct.
You could also just copy-paste that, though it's not open to change.

asp.net Run Javascript confirm from codebehind with custom text and return if OK selected

I have a grid on a page with a list of items - I have a column for tickbox - One use is to remove/delete item.
I have a button "Delete Item" - this runs some code behind to find the item ticked and if only one ticked I would like to ask the user - "Do you want to delete item ABC ... " i.e. showing the text of item selected - If they click OK continue.
I have tried a few options - closest is to use a hidden field to store the value as in below but the code behind goes to the line to read the hidden field before the confirm box comes up so its not going to pick up the value. The confirm box opens OK and message OK.
<script type="text/javascript">
function Confirm(txt) {
if (confirm(txt)) {
hdnResultValue = 1
}
}
</script>
<asp:HiddenField ID="hdnResultValue" Value="0" runat="server" />
<asp:Button ID="DelItem" runat="server" Text="Remove Item"/>
In code behind
Page.ClientScript.RegisterStartupScript(Page.GetType(), "myconfirm", "Confirm('" & txtMsg & "');", True)
If hdnResultValue.Value = 1 Then
'Code to delete
End If
Appreciate any ideas on getting this to work or alternatives.
Reply to Jon:-
Thanks Jon - I had a go at that but doesn't get the itemname - suspect its because I need to reference the grid - presume rather than "this" I need the gridID but this didn't work either.
Below main part of page:-
In console first log for "this" came up empty. I have the button sitting above the grid not as part of the grid!.
<script type="text/javascript">
function confirmClick() {
var itemName;
itemName = $(this).closest("tr").find("td:eq(2)").text();
//AS I haven't tested this lets add some debugging
//Check $(this) exists
console.log($(this));
//Check we got a tr
console.log($(this).closest("tr"));
//Check we got the target td
console.log($(this).closest("tr").find("td:eq(2)"));
return confirm("Are you sure you want to delete: " + itemName);
confirm(txt)
}
</script>
<div>
<asp:Button ID="DelItem" runat="server" Text="Delete Item" OnClientClick="return confirmClick();"/>
</div>
<asp:GridView ID="ItemList" runat="server">
<Columns>
<asp:TemplateField >
<ItemTemplate>
<asp:CheckBox ID="Select" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ItemID" HeaderText="ItemID" Visible="True">
</asp:BoundField>
<asp:BoundField DataField="ItemName" HeaderText="Item Name" Visible="True">
</asp:BoundField>
</asp:GridView>
The probelm with your approach is that by the time your javascript is triggered the page has already been posted back. So then when the client clicks "OK" the page will have to be posted back yet again.
The rule to remember is javascript is executed client side in the browser, vb.net on the server. Also remember that the whole serverside code is executed before the page (HTML/CSS/javascript) is returned to the browser. So in your current example the hdnResultValue.Value = 1 check is going to happen before the javascript is executed, as the page has yet to be sent to the browser.
What you need to do is trigger the javascript before the page is posted back
<asp:Button ID="DelItem" runat="server" Text="Remove Item" OnClientClick="return confirmClick(this);"/>
Then have your javascript already on the page, I'm going to use the incredibly helpful jQuery library to get the text for the item:
<script type="text/javascript">
function confirmClick(itemClicked) {
var itemName;
//If you have a class on the colum with the item for this example
//class="itemName"
//itemName = $(itemClicked).closest("tr").find(".itemName").text();
//If you don't have a class you could use the columns index
//3rd column for this exampl
//Index is 0 based
itemName = $(itemClicked).closest("tr").find("td:eq(2)").text();
//AS I haven't tested this lets add some debugging
//Check $(this) exists
console.log($(itemClicked));
//Check we got a tr
console.log($(itemClicked).closest("tr"));
//Check we got the target td
console.log($(itemClicked).closest("tr").find("td:eq(2)"));
return confirm("Are you sure you want to delete: " + itemName);
}
</script>
Don't forget to include the jQuery library!
Your other option is yo use AJAX for an asynchronous post back to generate the confirm message.
Here's an article outlining how to use the ModalPopUpExtender to use a fancier confirm: http://mattberseth.com/blog/2007/07/confirm_gridview_deletes_with.html.
Update A quick bug fix. I forgot to pass through the item bein click. It has been added as a parameter to the javascript function.
Demo of the script in action
Update 2 - Get Text of checked row
Change button to (we've taken out the parameter):
<asp:Button ID="DelItem" OnClientClick="return confirmClick();" runat="server" Text="Remove Item" />
Change your script to
function confirmClick() {
//<%= ItemList.ClientId %> gets the rendered client side ID of your gridview
var table = $("<%= ItemList.ClientId %>");
var checkedRow = $(table).find("tr").has("input:checked");
var itemName = $(checkedRow).find("td:eq(2)").text();
return confirm("Are you sure you want to delete: " + itemName);
}
Script Demo
To set value of hidden field do
document.getElementById("hdnResultValue").value = 1;

Javascript-error on finding object

im stuck with Javascript in Asp.net...
I made a TextBox named tbValidFrom and another named tbValidTo.
I also made two ModalPopups.
Then i try to open the ModalPopupExtenders when the TextBoxes get focus:
<script type="text/javascript">
$('#tbValidTo').focus(function () {
$find('ModalPopupExtenderNV1').show();
})
$('#tbValidFrom').focus(function () {
$find('ModalPopupExtenderNV2').show();
})
</script>
but it doesnt finds tbValidTo or ModalPopUpExtender ?
Runtime-Error in Microsoft JScript: Object expected
Here is one of the two ModalPopupExtenders and TextBoxes:
<asp:TextBox ID="tbValidFrom" runat="server"></asp:TextBox>
<asp:UpdatePanel ID="UpdatePanelNV2" runat="server" RenderMode="Inline" UpdateMode="Conditional">
<ContentTemplate>
<cc1:ModalPopupExtender ID="ModalPopupExtenderNV2" runat="server" TargetControlID="HiddenField6"
PopupControlID="PanelNewVersion" BackgroundCssClass="modalBackground" BehaviorID="ModalPopupExtenderNV2"
Enabled="True" />
<asp:HiddenField ID="HiddenField6" runat="server" />
</ContentTemplate
</asp:UpdatePanel>
The same as above is with the other ModalPopupExtender and TextBox...
Help would be really nice.
Thanks
Edit: Yes i use a masterpage!
Fails where it is marked yellow.
your jQuery syntax is wrong.
change your script to:
<script type="text/javascript">
$('#tbValidTo').focus(function () {
$(this).find('#<%=ModalPopupExtenderNV1.ClientID%>').show();
});
$('#tbValidFrom').focus(function () {
$(this).find('#<%=ModalPopupExtenderNV2.ClientID%>').show();
})
</script>
elements that has runat="server" will eventually end with a different ID than you entered in the aspx file.
i used the <%= %> to get the 'final' id.
hope that helps
Seeing that markup there is two chances for the issues.
With the ModalPopupExtender.
Where you have given the panel "PanelNewVersion" . Seems like its missing in the markup.
In the Javascript code. If you want to hide that Popup, give the name of the panel. NOt the name of the ModalPopupextender.
Also you have given an update panel there in page, so you can easily handle the modalpopup in any srever side event of your textbox.
Otherwise, if you want to use the Modal popup ijn client side, use jQuery Modalpopup. That will the better option.
ASP.NET Can modify the ID's of elements, if you use a Masterpage the element id's will be modified to something like the following : ctl001_ContentPlaceHolder1_tbValidFrom
To get around this ASP.NET modification of your elements you can use ASP.NET Inline Expressions to get the rendered ID from the object.
See the answer to the following question for more information on ASP.NET Inline Expressions
You can look at changing the Client ID Mode (The way ASP.NET Modifies IDs when the page is rendered) here :
ASP.NET Client ID Modes
EDIT :
The AjaxControlToolkit's ModalPopupExtender is not rendered on the page as a html element, therefore you cannot find this item using the ClientID of the ModalPopupExtender.
You must use the BehaviourID to call the show function on.
The below code should work correctly :
$('#<%= tbValidTo.ClientID %>').focus(function () {
$find('ModalPopupExtenderNV1').show();
})
$('#<%= tbValidFrom.ClientID %>').focus(function () {
$find('ModalPopupExtenderNV2').show();
});
This will find the textbox object using the ASP.NET Inline expressions to find the client ID and will then find the behaviour ID and execute the Show method.
Example Markup :
<script type="text/javascript">
$(document).ready(function() {
$('#<%= tbValidFrom.ClientID %>').focus(function () {
$find('ModalPopupExtenderNV2').show();
});
});
</script>
<asp:TextBox ID="tbValidFrom" runat="server"></asp:TextBox>
<asp:UpdatePanel ID="UpdatePanelNV2" runat="server" RenderMode="Inline" UpdateMode="Conditional">
<ContentTemplate>
<cc1:modalpopupextender id="ModalPopupExtenderNV2" runat="server" targetcontrolid="HiddenField6"
popupcontrolid="PanelNewVersion" backgroundcssclass="modalBackground" behaviorid="ModalPopupExtenderNV2"
enabled="True" />
<asp:HiddenField ID="HiddenField6" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Panel ID="PanelNewVersion" runat="server">
testing panel
</asp:Panel>

Creating a Button Click Event and Validating TextBoxes using Javascript

I am having so much trouble with this. I have looked everywhere so I hope someone can either explain to me how to do this or show me. Here's my problem:
I have a DataGrid filled with DataBound Items (ItemTemplate) which was created using ASP.Net.
My reason for the ItemTemplates over a regular DataBound field is to enable the Edit Mode of the DataGrid. In my ItemTemplates, I have labels to display the data and two option buttons (Edit/Delete). I've got the buttons working in the code behind (C#).
Edit places the DataGrid in Edit Mode. In the EditItemTemplates I've got DropDownLists, TextBoxes, and a Save button in place of the Edit button.
The Save button also works with the code I've written for it. All-in-all, the DataGrid works beautifully and displays everything neatly. However, there is one final job I want the Save button to do: I want it to check the TextBoxes and validate that the values entered match the criteria I have set (keep in mind that these are in EditItemTemplates).
I have Javascript already written that will check for validation. I want a modal window (that I have already set up) to display and I want the CSS of the TextBoxes in question to change.
I want to do this using Javascript but my problem is that I can't check for the Save button to create the Click event and I can't 'locate' the TextBoxes to validate them. Is there a way I can 'find' those elements while the DataGrid is in Edit Mode?
Here's a small bit of the code used to create the DataGrid if it helps:
<asp:DataGrid ID="dgCamsizer" CssClass="data" runat="server" AutoGenerateColumns="False"
GridLines="None" OnItemCommand="dgCamsizer_ItemCommand" ShowHeader="true">
<Columns>
<asp:TemplateColumn HeaderStyle-CssClass="infoHeaderDG">
<HeaderTemplate>
Operator</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="Operator" Text='<%# DataBinder.Eval(Container.DataItem, "Operator") %>'
runat="server" /></ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="EditOper" Width="40px" Text='<%# DataBinder.Eval(Container.DataItem, "Operator") %>'
runat="server"></asp:TextBox></EditItemTemplate>
<HeaderStyle CssClass="infoHeaderDG"></HeaderStyle>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderStyle-CssClass="infoHeaderDG">
<ItemTemplate>
<asp:Button ID="Edit" Text="Edit" CommandName="Edit" runat="server" /></ItemTemplate>
<EditItemTemplate>
<asp:Button ID="Save" Text="Save" CommandName="Save" runat="server" /></EditItemTemplate>
<HeaderStyle CssClass="infoHeaderDG"></HeaderStyle>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
Perhaps I should re-phase my question: I managed to 'find' the TextBoxes thanks to Zetlen. I've also managed to get the values. Now... How do I use those values to test for validation?
Here is the code I used to get the values:
$("#<%=dgCamsizer.ClientID %> :text").each(function () {
alert($(this).val());
});
ASP.NET webforms are hard to work with in JavaScript, because the IDs of your HTML elements change during the page lifecycle! The input you're calling "EditOper" will get an HTML ID of something like "dgCamSizer_ctl102_EditOper". One thing you can do is collect these elements on pageload in a cache of DOM element references. I recommend using jQuery or a similar DOM querying library.
<script type="text/javascript">
$(document).ready(function() {
var $editorElms = {},
idSeparator = "_"; // the underscore is ASP.NET's default ID separator, but this can be changed if you wish with the IDSeparator property.
$('#dgCamSizer input').each(function() {
$editorElms[this.id.split('_').pop()] = $(this);
});
// now you can access every input using the $editorElms hash.
// e.g.
function someValidationRoutine() {
if (!$editorElms.EditOper.val()) {
someErrorDisplayer("EditOper must not be blank.");
return false;
}
}
})
</script>
And, again using jQuery, the Save button shouldn't be too tough to find.
var $saveButton = $('#dgCamSizer :submit[value=Save]');
So you can bind the event that way:
$saveButton.click(function(e) {
if (!someValidationRoutine()) {
e.preventDefault();
}
});
This is not the most high-performance solution--selectors of that complexity are always a bit slower. But it gets the job done without messing too much with the DataGrid.
So I managed to solve my own problems and answer my own question. I was able to get the id's of all of the TextBoxes and I even placed them into an array to be used for my validations. Here's what I used to do all of this:
var i = 0;
var data = [];
$("#<%=dgCamsizer.ClientID %> :text").each(function () {
data[i] = $(this).attr("id");
i++;
});

Populate a TextBox from a DropDownList selection ASP.NET/Javascript

I have a DDL and ASP.NET Textbox. I would like to populate the text box with the option I choose from the DDL. I need this to be instant and not use postbacks so it would seem JavaScript would be the obvious choice here. I have done quite a bit of searching but everything I have found seems to be for standard HTML (Selects and Inputs) and these do not appear to work with ASP objects:
<asp:DropDownList runat="server" ID="DDLSalesPerson" DataValueField="keyid" DataTextField="FullName" />
<asp:TextBox runat="server" id="txtSalesPerson" />
My DDL is populated from SQL in the code-behind page.
Can somebody assist with the appropriate code I should use? Thanks.
ASP.Net controls render as standard HTML elements on the browser. In script, you can get a reference to them by using the ClientID property of the ASP.Net control.
Put this in a script block in your aspx:
var ddl = document.getElementById('<%=DDLSalesPerson.ClientID %>');
var textBox = document.getElementById('<%= txtSalesPerson.ClientID%>');
Now you have references to the DOM objects for the select and input elements that the ASP.Net controls rendered and you can use the techniques you've already learned on the HTML elements.
Additional info
You need to add an onchange attribute to your DropDownList control as such:
<asp:DropDownList runat="server" ID="DDLSalesPerson" DataValueField="keyid" onchange="ddlChange();" DataTextField="FullName" />
and then put this script block in your aspx
<script type="text/javascript">
function ddlChange()
{
var ddl = document.getElementById('<%=DDLSalesPerson.ClientID %>');
var textBox = document.getElementById('<%= txtSalesPerson.ClientID%>');
textBox.value = ddl.options[ddl.selectedIndex].text;
}
</script>
As you change the dropdown list, you'll see the textbox update. Tested in IE and Chrome.
Since you've pointed out that you're a JavaScript beginner, may i suggest you use an updatepanel control. An updatepanel allows you to execute server code without refreshing the page. Simply place the dropdownList and the textbox in the same updatepanel or in two separate updatepanels and write the code for the textbox to update based on the dropdownlist selection. Make sure to set the dropdownlist to do autopostback.
The asp markup is as follows:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:DropDownList ID="ddlList" runat="server"
AutoPostBack="True">
<asp:ListItem>-select-</asp:ListItem>
<asp:ListItem>option 1</asp:ListItem>
<asp:ListItem>option 2</asp:ListItem>
</asp:DropDownList>
<asp:TextBox ID="txtTextBox" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
The codebehind in vb is as follows:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If ddlList.Text <> "-select-" then
txtTextBox.Text = ddlList.text
End If
End Sub
If you're new to JavaScript, use the jQuery library (simply provide references to the CDN-hosted jQUery files at google.com) and then you can use the following code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
$("#DDLSalesPerson").change(function () {
$("#txtSalesPerson").val($(this).val());
});
</script>

Categories