Bind unique click event to each item in repeater (ajax/jquery) - c#

ok so I have this repeater:
<asp:Repeater runat="server" ID="rep" >
<ItemTemplate>
<tr>
<td>
<div id="resultDiv">
click me
</div>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
and i have this jquery ajax call:
$(document).ready(function () {
$("#resultDiv").click(function () {
$.ajax({
type: "POST",
url: "Page.aspx/GetDate",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
// Replace the div's content with the page method's return.
$("#resultDiv").text(msg.d);
}
});
});
});
the problem is that this only works for the first div inside the repeater. If i click any other divs, the click event isn't being fired.
I know this is because they all have the same id, being "resultDiv".
I am now looking for a way of giving them unique ID's, which is something I can do like this: (inside the repeater itemtemplate)
<td>
<div id="resultDiv_<%#Eval("divId") %>">
click me
</div>
This gives all the divs inside the repeater a unique ID, but this way the ajax click event doesnt fire anymore because
$("#resultDiv").click(function () {
resultDiv is now something like resultDiv_1 or resultDiv_2.
so im looking for something to bind a click event to each div inside the repeater. I tried doing it like this in the ajax call:
$("#<%#Eval("divId") %>").click(function ()
but this doesn't work and gives me all kinds of errors.
Is there any way i can do this ? Please not that I do not want to use updatepanels.

If you need a live event handler, you should use on :
$("body").on('click', '#resultDiv', function(e) { });
If you want to handle all #resultDiv the same way (by using resultDiv_1 or resultDiv_2) you could use :
$("body").on('click', 'div[id^=resultDiv]', function(e) { });
You might use classes instead of ID's because they aren't unique, you could easily play with them with addClass or removeClass !
In your case, I would add the same class to each div, and pass a parameter into some data-attr (if you need to have each click to call a different task) :
<div id="resultDiv" class="result" data-some-var="some-param">
click me
</div>
And than on your event :
$("body").on('click', '.result', function(e) {
var param = $(this).attr('data-some-var');
//send or do something different according to the param
});

Related

Struggling to ASP.NET C# Ajax novice question

I changed the code with a simple like these
<script src="http://code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#RadioButtonYes').click(function () {
var enterdata = document.getElementById("RadioButtonYes").value;
$.ajax({
type: "GET",
url: "radiobutton03ask.aspx/SyncData",
contentType: "application/json charset=utf-8",
dataType: "json",
data: { 'data': enterdata },
success: function (response) {
text1 = "ajaxyes";
alert(text1);
},
failure: function (response) {
alert(response.d);
}
});
});
$('#RadioButtonNo').click(function () {
var enterdata = document.getElementById("RadioButtonNo").value;
$.ajax({
type: "GET",
url: "radiobutton03ask.aspx/SyncData",
contentType: "application/json charset=utf-8",
dataType: "json",
data: { 'data': enterdata },
success: function (response) {
text2 = "ajaxno";
alert(text2);
},
failure: function (response) {
alert(response.d);
}
});
});
});
</script>
<div>
<asp:RadioButton ID="RadioButtonYes" Text="Yes" runat="server" Checked="true" GroupName="G" />
<asp:RadioButton ID="RadioButtonNo" Text="No" runat="server" GroupName="G" />
</div>
.cs side
I tried to add some debugging messages, but it didn't work.
public partial class Radio_Button__radiobutton03ask : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public void SyncData(string data)
{
if (data != "")
{
if (data == "RadioButtonYes")
{
Response.Write("SyncDataYes");
//return RadioButtonYes;
}
else if (data == "RadioButtonNo")
{
Response.Write("SyncDataNo");
//return RadioButtonNo;
}
else
{
Response.Write("SyncDataOther");
}
}
}
}
I am helping the company to debug some old projects(C# webforms), but struggling to simple ajax.
The goal is when pressing the radio button run ajax "ajaxyes" and .cs "SyncDataYes" message normally, but the above code does not respond when pressed.
I have tried alot of fixes i found online but none seem to work well for, if someone could help, it would be greatly appreciated.
first, there is a LOT of issues here.
first up:
[WebMethod]
public void SyncData(string data)
Why are you marking/making the routine as "void". Void of course in c# means that the function will NOT return anything!!!! - That should be a first obvious issue!
And since you using this inside of the web page (as opposed to a separate asmx page? Then you need to set the routine as static - since NO page class instance will have been created here (there is NOT post back).
next up:
Response.Write("SyncDataNo");
WHY would you try and use Response.Write? Response write is ONLY for writing into a web page. But the WHOLE IDEA of ajax is the web page is not and will not be sent up to the server for code behind to operate on. So, response write does not make sense AT ALL here! It can't be used, and you can EVEN see that the compiler does not allow this (now that you fixed and removed the void from that routine).
A so called "ajax" call?
The idea here is that you do NOT have to post back the web page. This is great since you don't get the browser "spinner" and all that waiting time. It also great since it runs VERY fast since you don't and are NOT posting the web page back to the server.
Of course the big downside is then the code behind can't see nor use, nor modify any of the controls on the web page. (since the web page is still sitting on the users desktop). So code behind for a web method can't see nor modify controls on the page (the calling JavaScript and ajax call HAS do to that change of controls).
So, lets use all of the above information, and fix this code.
Lets make a simple C to F temperature converter.
So, first up, that web method is to return a value, so we remove the void.
next up, as I stated, the page class "instance" is NOT re-created when we call such a web method, so that method ALSO MUST be marked as static. (I assume you know what that means, right???).
Ok. So the web method should look like this:
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public static Double ConvertToC(Double MyC)
{
Double CelResult = (MyC * 1.8) + 32;
return CelResult;
}
So, we HAVE to make this routine static. (the page class is not re-reated, and the web page is STILL sitting on the users desktop).
So, say our markup looks like this:
<div style="text-align:right;width:20%">
<label style="font-size:large">Enter Celsious Tempature</label>
<asp:TextBox ID="txtC" runat="server" style="font-size:large;margin-left:5px;text-align:center"
TextMode="Number" Width="80px" Wrap="False"
ClientIDMode="Static">
</asp:TextBox>
<br /> <br />
<div style="text-align:center">
<asp:Button ID="cmdConvert" runat="server" Text="Convert to °F" CssClass="btn"
OnClientClick="MyConvert();return false"/>
</div>
<br />
<label style="font-size:large">Fahrenheit</label>
<asp:TextBox ID="txtF" runat="server" style="font-size:large;margin-left:5px;text-align:center"
Width="80px" Wrap="false"
ClientIDMode="Static">
</asp:TextBox>
</div>
<script>
function MyConvert() {
var txtC = $("#txtC");
var txtF = $("#txtF");
$.ajax({
type: "POST",
url: "Autocom.aspx/ConvertToC",
data: JSON.stringify({ MyC: txtC.val()}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (MyReturn) {
txtF.val(MyReturn.d);
},
error: function (xhr, status, error) {
var errorMessage = xhr.status + ': ' + xhr.statusText
alert('Error - ' + errorMessage)
}
});
}
I'm also a bit lazy, so I used clientID mode = static, as that makes the jQuery selector nice and easy to type in.
So, when we run the above, we get this result:
so, now your "mess".
it not particular what you goal here is with your sample.
(going for coffee, but study, and try the above).
Edit: Try this sample code
Your c# method in the page:
[WebMethod]
public static string SyncData(string data)
{
string sResult = "";
if (data != "")
{
if (data == "Yes")
{
sResult = "SyncDataYes";
}
else if (data == "No")
{
sResult = "SyncDataNo";
}
else
{
sResult = "SyncDataOther";
}
}
return sResult;
}
And your markup is this:
<script src="http://code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"></script>
<asp:RadioButton ID="RadioButtonYes" Text="Yes" runat="server"
Checked="true" GroupName="G"
onclick="MyBtnClick('Yes')"
ClientIDMode="Static"
/>
<asp:RadioButton ID="RadioButtonNo" Text="No" runat="server"
GroupName="G"
onclick="MyBtnClick('No')"
ClientIDMode="Static"
/>
<br />
<h3>Result</h3>
<asp:TextBox ID="TextBox1" runat="server" ClientIDMode="Static"></asp:TextBox>
<script>
function MyBtnClick(sYesNo) {
$.ajax({
type: "POST",
url: "TestAjax.aspx/SyncData",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify({data : sYesNo }),
success: function (MyResult) {
$('#TextBox1').val(MyResult.d);
},
failure: function (MyResult) {
alert('error');
}
});
}
</script>
Since ASP run at server control's ID will be generated different ID in client side, so these 2 event handlers binding will not work.
$('#RadioButtonYes').click(function () {...}
$('#RadioButtonNo').click(function () {...}
You could try 2 solutions:
Using control's ClientID for event binding
$('#<%=RadioButtonYes.ClientID%>').click(function () {...}
$('#<%=RadioButtonYes.ClientID%>').click(function () {...}
Adding ClientIDMode="Static" attribute to ASP control
<asp:RadioButton ID="RadioButtonYes" Text="Yes" runat="server" ClientIDMode="Static" Checked="true" GroupName="G" />
<asp:RadioButton ID="RadioButtonNo" Text="No" runat="server" ClientIDMode="Static" GroupName="G" />
** UPDATE:**
Your code also has two more problems:
1 - DataType of your ajax request (json) does not match with response type from server code (text/plain). You could check demo of not matching dataType of ajax request here: https://jsfiddle.net/p2yzLqu1/3/
2 - You were using wrong ajax's callback function failure. We should use done (success) and fail (error) callback functions instead. Please check sample of using done and fail callback at above demo.

RequiredFieldValidator attached to DropDownList does not fire after appending options with jquery

I'm building an ASP.NET page in C#. There are 2 dropdownlists on the page, both have a required field validator. The first ddl is bound from codebehind. The second ddl is populated with a jquery ajax call to a WebMethod based on what was selected in the first ddl.
If I submit the form without selecting any values in either ddl the validators fire as expected. However, when I select a value in the first ddl then select a value in the second ddl and submit the form the Page.IsValid property is false. If I check the validators collection in the Page object and view the validator bound to the second ddl its valid property is false.
I don't know what else to try. I've tried calling ValidatorEnable and ValidatorValidate to try to re-register the validator on the client after selecting a value in the second ddl but it's doesn't work.
Can someone tell me what's going? How do I fix this? I really want to avoid using a postback to populate the second ddl. If anyone has any ideas I'd really appreciate some help.
Here's the code
<asp:RequiredFieldValidator runat="server" ControlToValidate="ddlState" Display="Dynamic" ErrorMessage="Required" InitialValue="" ValidationGroup="County" />
<asp:DropDownList ID="ddlState" runat="server" AutoPostBack="false" ValidationGroup="County" />
<asp:RequiredFieldValidator runat="server" ControlToValidate="ddlCounty" Display="Dynamic" ErrorMessage="Required" InitialValue="" ValidationGroup="County" />
<asp:DropDownList ID="ddlCounty" runat="server" AutoPostBack="false" ValidationGroup="County" />
$('#<%=ddlState.ClientID %>').change(function() {
$('#<%=ddlCounty.ClientID %>').find('option').remove();
var counties = $.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "County.aspx/GetCounties",
data: "{'state':'" + $(this).val() + "'}",
dataType: "json",
dataFilter: function (data) { return data; },
success: function(data) {
var d = jQuery.parseJSON(data.d);
$('#<%=ddlCounty.ClientID %>').append('<option value=""> - select - </option>');
$.each(d, function(i, val){
$('#<%=ddlCounty.ClientID %>').append('<option value="'+ val +'">'+ val +'</option>');
});
},
error: function (jqXHR, error, errorThrown) {
if (jqXHR.status && jqXHR.status == 400) {
alert("An error occurred. Please try again.");
//alert(jqXHR.status + " -- " + jqXHR.responseText);
}
}
});
});
Thanks
My guess would be that the server don't know that the DropDownList have values associated with it. He think they don't have values so don't validate them.
I think you would have to do the same databinding in server code on the selected index changed event of the ddlState.
private void ddlState_SelectedIndexChanged(e as args) : ddlState.SelectedIndexChanged {
// Do your databinding for ddlCountry;
}

DropDownList with Textbox Input as filter criteria

I need to have a DropDownList or equivalent in ASP.NET MVC in a View, which is populated with a bunch of entries from a database.
When selected, the DropDownList should produce the List as usual, with the exception that the user can enter text into it, at which point the items in the DropDownList will be filtered based on the entered text.
The user should however still only be able to choose one of the options in the list.
It could be any other control, but preferably NOT a 3rd party thing.
It is possible by writing some jQuery code. But it is already available and it is open source, widely used
Use jQuery chosen and configure like below
$(".select").chosen();
I found a decent method that works.
The only problem with this is that it requires 2 separate controls (DropDownList and TextBox), but other than that, works beautifully.
HTML Code (declaration of controls) is:
<table>
<tr>
<td>
<div>
<%: Html.Label("Search Filter:")%>
</div>
</td>
<td>
<div>
<%: Html.TextBox("textBoxForFilterInput")%>
</div>
</td>
</tr>
<tr>
<td>
<div>
<%: Html.Label("The List")%>
</div>
</td>
<td>
<div>
<%: Html.DropDownList("listOfOptions")%>
</div>
</td>
</tr>
</table>
The JavaScript code is:
$(function () {
var opts = $('#listOfOptions option').map(function () {
return [[this.value, $(this).text()]];
});
$('#textBoxForFilterInput').keyup(function () {
var rxp = new RegExp($('#textBoxForFilterInput').val(), 'i');
var optlist = $('#listOfOptions').empty();
opts.each(function () {
if (rxp.test(this[1])) {
optlist.append($('<option/>').attr('value', this[0]).text(this[1]));
}
});
});
});
Then just populate #listOfOptions and then you should be good to go.
Alternatively, you could hook it up to a predefined list/array or fetch it from a database like I do.
This works like a charm, very simple and super fast.
Thanks to DMI for sending me on the right path.
His work on this can be found here.
For this .autoComplete of Jquery can be used.
HTML is like
<table><tr><td><input type="textbox" id="textBoxid" /> <div id="targetDiv" style="z-index:10"></div>
Jquery code will be like
$(function () {
$("#textBoxid").autocomplete({
appendTo: "#targetDiv",
position: { at: "bottom bottom" },
source: function (request, response) {
$.ajax({
url: '#Url.Action("ActionMethod", "Controller")',
type: "POST",
dataType: "json",
data: { searchString: request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.ColumnValue, Id:item.ColumnId }
}))
}
})
},
select: function (event, ui) {
if (ui.item) {
// for saving the selected item id or any other function you wanna perform on selection
$('#hiddenfield').val($.trim(ui.item.Id));
}
}
});
Action Method will be like
[HttpPost]
public JsonResult MaterialDesc(string searchString)
{
// On searchString basis you can have your code to fetch data from database.
}
hope it can help you
:)

disable/hide all link button using jquery in repeater

I have a repeater which will have a link button per row here is the code:
<asp:Repeater ID="rpt_OutstandingBCsForClient" runat="server">
<ItemTemplate>
<div class="pay">
<table>
<tr>
<td>
<div style="width: 230px;">
<asp:Label ID="lbl_Len" runat="server" ></asp:Label>
</div>
</td>
<td align="left">
<div style="width: 80px;">
<asp:LinkButton ID="lnkbtn_Remove" runat="server">Remove</asp:LinkButton>
</div>
</td>
</tr>
</table>
</div>
</ItemTemplate>
</asp:Repeater>
I want to disable or hide all Linkbuttons with id 'lnkbtn_Remove' on button click, so i have done this but still it doesn't work, if put an alert after var linkButton1 I get an object, but it doesn't disable or hide the link button:
$("input[id$='btnP']").click(function (e) {
var linkButton1 = $('[id*="lnkbtn_Remove"]');
$.ajax({
type: "POST",
url: "MyPage.aspx/Take",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
if (msg.d.indexOf('https://') > -1) {
$('#lnkbtn_Remove').attr("disabled", true);
}
else {
}
}
});
e.preventDefault();
});
Because your LinkButtons are server-side controls, their client-side IDs will not be lnkbtn_Remove but somethingsomethingsomethinglnkbtn_Remove.
Thus, try $('[id$="lnkbtn_Remove"]') instead of $('#lnkbtn_Remove'). id$= means "ID ends with".
As well as the selector issue, you also apparently can't disable a LinkButton, so you need to .remove() or .hide() it.
OnbuttonClick If you want to disable this button then you can use...
$('[id*=lnkbtn_Remove]').attr("disabled", true);
or if you want to hide this then simply you can use
$("#lnkbtn_Remove").hide();
Your id will be changed by asp.net for each link button. Use wild cards.
Change
$('#lnkbtn_Remove').attr("disabled", true);
To
$('[id*=lnkbtn_Remove]').attr("disabled", true);
Try to set CSS class for your buttons like "linkButtonRemove", so all link buttons from your repeater will have the same class. I think it's better way than using IDs here...
And then in jquery try to hide found elements:
$('.linkButtonRemove').hide();
or through adding css style
$('.linkButtonRemove').css('display', 'none');
$('#lnkbtn_Remove').click(function(){return false;})

Jquery .ajax async postback on C# UserControl

I'm working on adding a todo list to a project system and would like to have the todo creation trigger a async postback to update the database. I'd really like to host this in a usercontrol so I can drop the todo list onto a project page, task page or stand alone todo list page.
Here's what I have.
User Control "TodoList.ascx" which lives in the Controls directory.
The script that sits at the top of the UserControl. You can see where I started building jsonText to postback but when that didn't work I just tried posting back an empty data variable and removed the 'string[] items' variable from the AddTodo2 method.
<script type="text/javascript">
$(document).ready(function() {
// Add the page method call as an onclick handler for the div.
$("#divAddButton").click(function() {
var jsonText = JSON.stringify({ tdlId: 1, description: "test test test" });
//data: jsonText,
$.ajax({
type: "POST",
url: "TodoList.aspx/AddTodo2",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
alert('retrieved');
$("#divAddButton").text(msg.d);
},
error: function() {
alert("error");
}
});
});
});</script>
The rest of the code on the ascx.
<div class="divTodoList">
<asp:PlaceHolder ID="phTodoListCreate" runat="server">
<div class="divTLDetail">
<div>Description</div>
<div><asp:TextBox ID="txtDescription" runat="server"></asp:TextBox></div>
<div>Active</div>
<div><asp:CheckBox ID="cbActive" runat="server" /></div>
<div>Access Level</div>
<div><asp:DropDownList ID="ddlAccessLevel" runat="server"></asp:DropDownList></div>
</div>
</asp:PlaceHolder>
<asp:PlaceHolder ID="phTodoListDisplayHeader" runat="server">
<div id="divTLHeader">
<asp:HyperLink ID="hlHeader" runat="server"></asp:HyperLink>
</div>
</asp:PlaceHolder>
<asp:PlaceHolder ID="phTodoListItems" runat="server">
<div class="divTLItems>
<asp:Literal ID="litItems" runat="server"></asp:Literal>
</div>
</asp:PlaceHolder>
<asp:PlaceHolder ID="phAddTodo" runat="server">
<div class="divTLAddItem">
<div id="divAddButton">Add Todo</div>
<div id="divAddText"><asp:TextBox ID="txtNewTodo" runat="server"></asp:TextBox></div>
</div>
</asp:PlaceHolder>
<asp:Label ID="lbTodoListId" runat="server" style="display:none;"></asp:Label></div>
To test the idea I created a /TodoList.aspx page that lives in the root directory.
<uc1:TodoList runat="server" ID="tdl1" TodoListId="1" ></uc1:TodoList>
The cs for the todolist.aspx
protected void Page_Load(object sender, EventArgs e)
{
SecurityManager sm = new SecurityManager();
sm.MemberLevelAccessCheck(MemberLevelKey.AreaAdmin);
}
public static string AddTodo2()
{
return "yea!";
}
My hope is that I can have a control that can be used to display multiple todo lists and create a brand new todo list as well.
When I click on the #divAddButton I can watch it build the postback in firebug but once it completes it runs the error portion by alerting 'error'. I can't see why.
I'd really rather have the response method live inside the user control as well. Since I'll be dropping it on several pages to keep from having to go put a method on each individual page.
Any help would be appreciated.
I wasn't able to get the jquery ajax to work so I backed up and tried just putting the div and the jquery on the page itself and created a webservice.asmx page to handle the postbacks.
I'm still getting the error returned from the jquery and wondering if I've got something configured wrong or some other issue.
Here's the todo.aspx
<asp:Content runat="server" ContentPlaceHolderID="cpHolder" ID="ContentId">
<div id="divAddButton">Add Todo</div>
<script type="text/javascript">
$(document).ready(function() {
// Add the page method call as an onclick handler for the div.
$("#divAddButton").click(function() {
var jsonText = JSON.stringify({ Todo: { TodoId: 1, Description: "test test test"} });
//var jsonTextEmpty = jsonText.stringify({""});
$.ajax({
type: "POST",
url: "WebService.asmx/HelloWorld",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
alert('retrieved');
$("#divAddButton").text(msg);
},
error: function() {
alert("error");
}
});
});
});
The webservice.asmx is unchanged from the default bit Visual Studio created. Is there a way to find out what is causing the error?
In order to do this with jQuery as you describe, you need to sent it to a decorated method in your ASPX.cs file, you cannot send directly to the .ascx method. The good news is that the aspx.cs method can call the ascx one, so it is really pretty easy and you can just use it as a pass through to that.
[WebMethod]
public static string AddTodo2(myTodo todo2add)
{
//call your ascx method here
mymethod(todo2add.td1Id,todo2add.description);
return "yea!";
}
at the end of the aspx.cs, or in another class library put in your class so it knows how to decode the stuff:
public class myTodo
{
/// <summary>
/// web service/webmethod needs 0 parameter constructor
/// </summary>
public myTodo()
{
}
public myTodo(int tdlId, string description)
{
TdlId= tdlId;
Description= description;
}
public int TdlId;
public string Description;
}
slight change to the ajax call:
$("#divAddButton").click(function() {
var jsonText = JSON.stringify({myTodo:{ tdlId: 1, description: "test test test" }});
$.ajax({
type: "POST",
url: "TodoList.aspx/AddTodo2",
data: jsonText,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
alert('retrieved');
$("#divAddButton").text(msg.d);
},
error: function() {
alert("error");
}
});
});

Categories