Binding client side event to dyanamic datalist items using jquery - c#

I got stuck in a problem. I am loading elements in a datalist dynamically. and i am trying to bind click event on a column using jquery. It works fine when i use master page with it. as it follows the page life cycle and loading jquery after child page data binding. But when i use it in a normal page(without master page) it does not allow me to perform desired action. I know why is this happening, the reason is jquery is being loaded before elements binding. so jquery is not able to bind click event since it is not able to find those controls.
binding elements already have "item" class in them
here is my jquery code:
$(document).ready(function () {
$('.item').click(function () {
//do something here
});
});
code behind:
protected void Page_Load(object sender, EventArgs e)
{
using (TestEntites db = new TestEntites())
{
IEnumerable<Template> Test = from t in db.Template
where t.Customer == clsuser.CustomerID
&& t.Region == user.RegionID
select t;
dlTemplateGroups.DataSource = Test;
dlTemplateGroups.DataBind();
BindTemplates(db);
}
}

$(document).ready(function () {
$('body').on('click', '.item' ,function () {
//do something here
});
});
$('body') make it more specific based on your html

I also had the same problem once and this problem really is a pain.
Here is my solution:
Instead of binding with click create a function for example:
function reBinding()
{
$('.item').on("click",function () {
//do something here
});
}
and call this function after data binding is done. it will be good if you are using update panel.
ScriptManager.RegisterStartupScript(rptGridAlbum.GetType, "scriptname", "reBinding();", True)

Related

How can I add jQuery to a WebPart (to respond to certain events on the WebPart)?

I started down the path of adding an UpdatePanel to my Sharepoint page so that I can respond to events that take place (such as the checking of checkboxes and mashing of radio buttons, etc.). That so far has, however, been wrought with frustration and all that rot, as can be deduced from this question.
So I'm now probably going to traverse (no pun intended) the jQuery route and am trying to figure out/find out how to add jQuery to a WebPart.
Currenlty, I am dynamically creating controls in C# based on what a user selects in the WebPart's Editor (if they elect to show Section 1, I create all the controls for Section 1, etc.).
As an example, I'm currently conditionally creating a RadioButton in C# like so:
var radbtnEmployeeQ = new RadioButton
{
CssClass = "dplatypus-webform-field-input"
};
Now if I want to add jQuery to it, I can add an ID to it like so:
var radbtnEmployeeQ = new RadioButton
{
CssClass = "dplatypus-webform-field-input",
ID = "radbtnEmp"
};
...and then add jQuery of this nature (pseudocode):
$('radbtnEmp').click {
// visiblize/invisiblize other controls, assign certain vals to their properties
}
This seems feasible to me, but how do I go about adding jQuery to a WebPart? Is it a matter of adding a .js file at the same directory level as the *.ascx.cs file, and then referencing it from the *.ascx.cs file, or...???
UPDATE
For POC testing, I added a file to my project named "directpaydynamic.js" with this content:
<script>
$(document).ready(function () {
$('input:radio[name=radbtnEmp]:checked').change(function () {
if ($("input[name='radbtnEmp']:checked").val() == 'Employee?') {
alert("radbtnEmp checked");
}
else {
alert("radbtnEmp not checked");
}
});
});
</script>
(derived from an example here)
...and reference the .js file in my *.ascx.cs file like so:
SPWeb site = SPContext.Current.Web;
site.CustomJavaScriptFileUrl = #"C:\Projects\DirectPaymentWebForm\DirectPaymentSectionsWebPart\DPSVisualWebPart\directpaydynamic.js";
(I dragged the .js file onto the code to get the path)
However, running the solution and mashing the radiobutton causes neither alert() to display, so I reckon I've taken the road that was for a good reason less traveled.
UPDATE 2
Realizing I didn't need the script business (as this is a .js file, not an html file), I removed those, and also put an "at any rate" alert() in the jQuery:
$(document).ready(function () {
alert("What's new, pussycat, whoa-oh-oh-oh-OH-oh?");
$('input:radio[name=radbtnEmp]:checked').change(function () {
if ($("input[name='radbtnEmp']:checked").val() == 'Employee?') {
alert("radbtnEmp checked");
}
else {
alert("radbtnEmp not checked");
}
});
});
...but I still endure an alarming dearth of alerts...
Use below code on Page load method
string url = SPContext.Current.Site.ServerRelativeUrl;
if (!url.EndsWith("/"))
{
url += "/";
}
HtmlGenericControl styleCss = new HtmlGenericControl("link");
styleCss.Attributes.Add("rel", "stylesheet");
styleCss.Attributes.Add("type", "text/css");
styleCss.Attributes.Add("href", url + "Style Library/css/style.css");
HtmlGenericControl JsLink = new HtmlGenericControl("script");
JsLink.Attributes.Add("src", url + "Style Library/js/jquery.min.js");`enter code here`
this.Controls.Add(styleCss);
this.Controls.Add(JsLink);
The thing to do (or perhaps I should write, "a" thing to do) to get this to work is to add code like the following to the end of the WebPart's *.ascx file:
<script>
$(document).ready(function () {
alert("The ready function has been reached");
});
$(document).on("change", '[id$=ckbxEmp]', function () {
alert('Function has been reached');
if ($(this).is(":checked")) {
alert("Checked");
} else {
alert("Not checked");
}
});
</script>
The above works like a champ.

How to Check if ListBox is Empty on Client-Side

I created a javascript confirm as below.
<script Type="Text/Javascript">
function CheckListBox(lvi)
{
if(lvi == "")
{
if(confirm("Are you sure?"))
{
return true;
}
else
{
return false;
}
}
}
</script>
I need to test if the ListBox.Items control is empty... I already made reference on my aspx page
<script language="javascript" type="text/javascript" src="/JS/confirm.js"></script>
I want to know how to call it on my aspx.cs page . . . So I can pass the parameter:
string oi = Listbox_Clubes.Items.Count.ToString();//Its the parameter I want to pass
See this link for how to execute javascript from code behind
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(), "CheckListBox(" + Listbox_Clubes.Items.Count.ToString() + ");", false);
}
Note: you must add a ScriptManager control in aspx page.
For your javascript, you can get the value without the code-behind (this assumes the script code is in the same page, in order to get the client ID):
<script>
function ClickListBox() {
if ($("#<%= Listbox_Clubes.ClientID %>").val() === null) {
if (confirm("Are you sure?")) {
return true;
}
else {
return false;
}
}
}
</script>
Similarly, you don't use javascript to validate on the server side. The code you posted will return all items in the ListBox. Here is one way to get the count of the number of selected items (I'm using .ToString() based on the OP code example):
string oi = Listbox_Clubes.Items.Cast<ListItem>().Where(i => i.Selected).Count().ToString();
However, there is no reason why you would get this value and pass it back to the client-side to do validation (what it sounds like you want to do in your post). Mainly because this involves a post-back, and client-side validation, by its nature, should occur before post-back. Also, you will still need to do server-side validation, even when you have client-side validation.
Related: in the code-behind, you can test to see if anything is selected by:
bool hasValue = Listbox_Clubes.SelectedItem != null;
The .SelectedItem returns the selected item with the lowest index in the list control. When nothing is selected, this value is null... so you know if the value isn't null, then at least one item was selected.
If you want to require that they choose at least one item, you can use a RequireFieldValidator and let that handle both validations. If you haven't done much with ASP.NET validators, that would be one good thing to read up on.
It sounds like you probably should read more about client-side validation and server-side validation and how to use them... because it seems like you are mixing them up.
The count code is a modified version of code in ASP:ListBox Get Selected Items - One Liner?

Show/hide buttons based on a dropdown list

Currently I have an aspx page that contains a dropdown list and four buttons.
Based on the selection made in the dropdown list then a combination of the buttons are displayed.
I currently have this implemented so that when the user makes a selection I am using AutoPostBack and the selectedChanged server side event to determine which buttons to display and then set the Visible property of these buttons in this method.
Due to the fact that this posts back I don't think its a nice solution as the whole page is posting back. I would prefer to do this using JSON.
I made the following attempt but it doesn't seem to work:
$(document).ready(function () {
jQuery("#<%= MyDropdownList.ClientID %>").change(function () {
updateAvailableButtons(jQuery(this).val());
});
});
function updateAvailableButtons(selectedItemId) {
jQuery("h2").html("selectedItemId:" + selectedItemId);
jQuery.getJSON("MyPage.aspx/GetAvailableButtons?" + Id, function (data, textStatus) { debugger; });
}
Server side:
protected void GetAvailableButtons(int selectedItemId)
{
//based on the id here then then I show hide certain buttons.
button1.Visible = true;
button2.Visible = false;
button3.Visible = false;
button4.Visible = false;
}
I've never worked with JSON before so apologies if this is way off.
Similar task can be done using JavaScript. The problem is that you'll need to use a html control instead of an asp.net button control so that you can manipulate form the client side.

How to detect a postback in frontend (aspx)

I need to detect a postback in the frontend so I can use it with JQuery to change a class on page load. How can I do this?
You can check the IsPostBack property. Eg:
<script type="text/javascript">
$(function()
{
var isPostBack = <%=Page.IsPostBack.ToString().ToLower()%>;
if (isPostBack)
{
alert("Postback");
}
});
</script>
Stolen from this post:
On the server side have this
if(IsPostBack)
{
// NOTE: the following uses an overload of RegisterClientScriptBlock()
// that will surround our string with the needed script tags
ClientScript.RegisterClientScriptBlock(GetType(), "IsPostBack", "var isPostBack = true;", true);
}
On client side this
if(isPostBack) {
// do your thing
}
I put this variable inside the header tag of my asp.net web forms page.
<script type="text/javascript">
var isPostBack = ("true"==="<%= Page.IsPostBack ? "true" : "false" %>");
</script>
The var contains a Boolean. The comparison can probably be shortened.
Simple:
if you're using jquery it has to go after(jquery goes nuts otherwise):
$(document).ready(function(){
});
var isPostBack = <%=Convert.ToString(Page.IsPostBack).ToLower()%>;
Then
function whatever(){
if (isPostBack){
//Whatever you want to do
}else{
//Whatever else you want to do
}
}
I'm actually using it with jquery to show a web service status box then force a postback to refresh a ListView, so when it posts back it doesn't invoke the web service or show the status box just the updated ListView data.
$("a[href^='javascript:__doPostBack']").click(function () {
// do something
});

ASP.NET & C# & jQuery - looking for a better and usage solution

I have a little problem about using jQuery (I really do not know jQuery but I am forced to use it).
I am using Visual Studio 2008, ASP.NET web app with C#, Telerik controls on my pages. I am also using SqlDataSources (connecting to stored procedures) on my pages
My pages are based on a master and content pages and in content pages I have mutiviews.
In one of the views (inside one of those multiviews) I had made two radcombo boxes for country and city requirement like cascading dropdowns as parent and child combo boxes. I used old way for doing that, I mean I used update panel and in the SelectedIndexChange event of parent RadComboBox (country) I wrote this code:
protected void RadcomboboxCountry_SelectedIndexChanged(object o, RadComboBoxSelectedIndexChangedEventArgs e)
{
hfSelectedCo_ID.Value = RadcomboboxCountry.SelectedValue;
RadcomboboxCity.Items.Clear();
RadcomboboxCity.Items.Add(new RadComboBoxItem(" ...", "5"));
RadcomboboxCity.DataBind();
RadcomboboxCity.SelectedIndex = 0;
}
My child radcombo box can fill by this code, let me tell you how: the child SqlDataSource has a stored procedure that has a parameter and I fill that parameter with this line
hfSelectedCo_ID.Value = RadcbCoNameInInsert.SelectedValue;
RadcbCoNameInInsert.SelectedValue means country ID.
After doing that SelectedIndexChange event of parent RadComboBox (Country) could not be fired therefore I forced to set the AutoPostback property to true.
After doing that, everything was ok until some one told me can you control focus and keydown of your radcombo boxes (when you press the Enter key on the parent combobox [country], so child combobox gets focus -- and when you press upperkey on child radcombobox [city], parent combobox[country] gets the focus - for users that do not want to use mouse for input and choose items).
I told him this is web app, not win form and we can not do that. I googled it and I found jQuery the only way for doing that ... so I started using jQuery. I wrote this code with jQuery for both of them :
<script src="../JQuery/jquery-1.4.1.js" language="javascript" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
$('input[id$=RadcomboboxCountry_Input]').focus();
$('input[id$=RadcomboboxCountry_Input]').select();
$('input[id$=RadcomboboxCountry_Input]').bind('keyup', function(e) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 13) { -----------> Enter Key
$('input[id$=RadcomboboxCity_Input]').focus();
$('input[id$=RadcomboboxCity_Input]').select();
}
});
$('input[id$=RadcomboboxCity_Input]').bind('keyup', function(e) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 38) { -----------> Upper Key
$('input[id$=RadcomboboxCountry_Input]').focus();
$('input[id$=RadcomboboxCountry_Input]').select();
}
});
});
</script>
This jQuery code worked but autopostback=true of the parent RadComboBox became a problem because when SelectedIndexChange of the parent RadComboBox is fired after that Telerik Skins runs and after that I lost parent combobox focus and we should use mouse but we don't want it....
To fix this problem I decided to set AutoPostback of parent CB to false and convert
protected void RadcomboboxCountry_SelectedIndexChanged(object o, RadComboBoxSelectedIndexChangedEventArgs e)
{
hfSelectedCo_ID.Value = RadcomboboxCountry.SelectedValue;
RadcomboboxCity.Items.Clear();
RadcomboboxCity.Items.Add(new RadComboBoxItem(" ...", "5"));
RadcomboboxCity.DataBind();
RadcomboboxCity.SelectedIndex = 0;
}
to a public non static method without parameters and call it with jQuery like this (I used onclientchanged property of parent combobox like
onclientchanged = "MyMethodForParentCB_InJquery();"
instead of selectedindexchange event):
public void MyMethodForParentCB_InCodeBehind()
{
hfSelectedCo_ID.Value = RadcomboboxCountry.SelectedValue;
RadcomboboxCity.Items.Clear();
RadcomboboxCity.Items.Add(new RadComboBoxItem(" ...", "5"));
RadcomboboxCity.DataBind();
RadcomboboxCity.SelectedIndex = 0;
}
For doing that I read the below manual and do that step by step :
http://www.ajaxprojects.com/ajax/tutorialdetails.php?itemid=732
but this manual is about static methods and this is my new problem ...
When I am using static method like :
public static void MyMethodForParentCB_InCodeBehind()
{
hfSelectedCo_ID.Value = RadcomboboxCountry.SelectedValue;
RadcomboboxCity.Items.Clear();
RadcomboboxCity.Items.Add(new RadComboBoxItem(" ...", "5"));
RadcomboboxCity.DataBind();
RadcomboboxCity.SelectedIndex = 0;
}
I got some errors and this method could not recognize my controls and hidden field...
One of those errors:
Error 2 An object reference is required for the non-static field, method, or property 'Darman.SuperAdmin.Users.hfSelectedCo_ID' C:\Javad\Copy of Darman 6\Darman\SuperAdmin\Users.aspx.cs 231 13 Darman
Any idea or is there any way to call non static methods with jQuery?
(I know we can not do that but is there another way to solve my problem?)
Your problem is related to the interaction between .NET and jQuery. Basically, if you change values in the user interface using jQuery, .NET doesn't know anything about it. If you make an ajax call using jQuery, it doesn't know anything about .NET's controls.
The ajax method you found and started to implement is the right way to go. However, jQuery is going to make a true ajax call. Everything you do in code behind has to exist in that static function. It can create objects and do things with them, but no controls will exist when you enter this function at runtime (unlike using an updatepanel, which walks through the full page lifecycle).
So, something like this is not going to work:
public static void MyMethodForParentCB_InCodeBehind()
{
hfSelectedCo_ID.Value = RadcomboboxCountry.SelectedValue;
RadcomboboxCity.Items.Clear();
RadcomboboxCity.Items.Add(new RadComboBoxItem(" ...", "5"));
RadcomboboxCity.DataBind();
RadcomboboxCity.SelectedIndex = 0;
}
In the case above, you don't have access to any of the controls, so you're basically left with populating the control yourself using jQuery.
You'll need to send the selected value to the static method, create the new list item as a string, and return this to the ajax callback. Within the jQuery ajax callback you'll have to add the item into the list yourself.
public static string MyMethodForParentCB_InCodeBehind( string selectedvalue )
{
string rtrnString = SomeClass.GetValue( selectedvalue );
return rtrnString;
}
The following function in your presentation logic should retrieve this result and add it to your list using jQuery.
function AjaxSucceeded (result)
{
alert(result.d);
// result.d will have the value of the string passed back from the function
// it's up to you to populate the combobox using jQuery.
}
The side effect of doing this is that the .NET control no longer shares the same viewstate that it did before. Meaning, if the page does a postback, the new value entered into your combobox will not be available in codebehind. You most likely won't even get this far as you'll probably get view state errors.
You're kind of in a tough spot. You might want to look into using updatepanels, as you will have access to the controls in code behind.

Categories