I have an ASP.NET web app that is using JQuery autocomplete to build a nice dynamic combobox. One of the boxes on the page fires a change event that reloads another box. Basically like a UserGroup / Members scenario. My change event fires and repopulates the underlying select box, I then do a remove on the input and button that build the combobox - which all work great up to this point. My last line is to call the combobox method on the newly repopulated select which doesn't seem to fire ? The standard select shows with the new data but no JQuery Goodness. Any help is appreciated. Thanks.
On Change Event:
function GetAnalysts() {
$.ajax({
type: "POST",
url: "GetAnalystByGroup.ashx",
data: 'group=' + $("#<%=supportGroup.ClientID%>" + " option:selected").text(),
success: function (response) {
var analysts = eval(response);
$("#<%=assignedAnalyst.ClientID%>").children().remove();
$("#<%=assignedAnalyst.ClientID%>").append($('<option></option>').val('').html(firstoption));
for (var i = 0; i < analysts.length; i++) {
var text = analysts[i]['label'];
var val = analysts[i]['upn'];
$("#<%=assignedAnalyst.ClientID%>").append($('<option></option>').val(val).html(text));
}
//remove the JQ Combo then rebuild it
$("#<%=assignedAnalyst.ClientID%>JQ").remove();
$("#<%=assignedAnalyst.ClientID%>JQBut").remove();
$("#<%=assignedAnalyst.ClientID%>").show();
$("#<%=assignedAnalyst.ClientID%>").combobox();
},
error: function () {
}
});
}
I ended up working around the problem by coding the remove/show lines into a javascript pageload event and moving the AJAX call inside an update panel.
Related
This is a problem I haven't come across before.
I'm working on an MVC4 project. I'm using an asp button control because there isn't a Html Helper that can be used for a button (re: There's no #Html.Button !). My button code is:
<td><asp:Button ID="ButtonUndo" runat="server" Text="Undo"
OnClick="ButtonUndo_Click" AutoPostBack="true"/></td>
I went to the Designer tab and clicked on this button which produced the event handler:
protected void ButtonUndo_Click(object sender, EventArgs e)
{
RRSPSqlEntities db = new RRSPSqlEntities();
int id = (int)ViewData["ClientId"];
var updateAddress = (from a in db.Address
where a.PersonId == id
select a).SingleOrDefault();
updateAddress.Deleted = false;
db.SaveChanges();
}
I should add that this code was added to the same .aspx page wrapped in a script tag. Also within this section is the Page_Load method. The eventhandler is not within Page_Load.
The problem was found when I set a breakpoint and stepped through the code. Clicking my button shows that it doesn't hit my event handler at all. I don't know why this is, particularly as ASP created the event from clicking the button in Design mode.
Clicking my button shows that it doesn't hit my event handler at all.
This isn't all that surprising. ASP.NET MVC uses a completely different event model (i.e. it doesn't have one like web forms). However, what you're trying to do is very straight forward. In your controller build a new method, let's call it Undo:
public ActionResult Undo(int id)
{
RRSPSqlEntities db = new RRSPSqlEntities();
var updateAddress = (from a in db.Address
where a.PersonId == id
select a).SingleOrDefault();
updateAddress.Deleted = false;
db.SaveChanges();
return View("{insert the original action name here}");
}
and then in your markup, simply markup the input like this:
<form method="POST" action="/ControllerName/Undo">
#Html.HiddenFor(Model.Id)
<input type="submit" value="Undo" />
</form>
where the Model for the View you're on contains a property, I've called it Id, that is the id you want passed into Undo.
I usually prefer to make ajax calls. You can try:
<button type="button" class="button" onclick="ButtonUndo();" />
In the form:
<script>
function ButtonUndo() {
$.ajax({
type: 'POST',
url: '/controller/action',
data: 'PersonID=' + ID,
dataType: 'json',
cache: false,
success: function (result) {
//do stuff here
},
error: function () {
//do error stuff here
}
});
}
</script>
Controller:
[HttpPost]
public ActionResult Action(int PersonID)
{
//Do your stuff here
return new JsonResult { result = "something" };
}
(Sorry for any typos or syntax errors...I pulled from existing code that we use in a project.)
I am trying to write a generic table generator where I can tell it the function to call in the onclick event of each cell. The function is then defined somewhere else on the page.
The problem is I cannot get the page to evaluate the function at the right moment. I want it to convert my string to a function when it is building the DOM not when it fires the click event. Maybe this is not possible in Javascript/JQuery?
A simplified version of the code I originally wrote server-side in C# is:
string functionCall = "DoSomething(4);";
TableCell detailCell = new TableCell();
detailCell.Attributes.Add("onClick", functionCall);
functionCall = "DoSomething(5);";
detailCell = new TableCell();
detailCell.Attributes.Add("onClick", functionCall);
This then worked when it was rendered as html in the browser. It turned into:
function DoSomething(p)
{
alert(p);
}
<td onclick="DoSomething(4)"></td>
<td onclick="DoSomething(5)"></td>
I want to replicate this functionality in Javascript.
If I do:
var functionCall = 'DoSomething(4);';
$('#detailCell').attr('onclick', functionCall);
it won't fire the event in IE7 for some reason but fires it in Chrome.
If I do:
var functionCall = 'DoSomething(4);';
$('#detailCell1').click(function () { eval(functionCall); });
functionCall = 'DoSomething(5);';
$('#detailCell2').click(function () { eval(functionCall); });
then it doesn't change functionCall to a piece of text when the click event is added. Instead it evals functionCall WHEN the cell is clicked. This means the value of functionCall is now wrong.
e.g. it always does DoSomething(5) even if I click on detailCell1 because that was the last value of functionCall.
If I do:
var functionCall = 'DoSomething(4);';
$('#detailCell1').click(eval(functionCall));
it runs the function in functionCall immediately when adding the click event rather than when it is clicked.
I hope this makes some sense as it is difficult to explain.
Basically I just want to be able to do
<td onclick="any javascript I feel like storing in a string"></td>
using JQuery.
Is this even possible?
This is my first ever post on stackoverflow so please be gentle...
Try this...
var functionCall = 'DoSomething(4);';
$('#detailCell1').click((function (code) {
return function () {
eval(code);
};
}(functionCall)));
What happens here is that you capture the string at the time that you create the handler by assigning it to the parameter 'code'.
In your current scenario the click handler uses the value of the string at the time it is clicked and not at the time the handler is created.
This is called a closure!
(function (code) {
return function () {
eval(code);
};
}(functionCall));
The functionCall value is assigned to the code parameter.
Now when you change functionCall the code parameter still refers to the old value.
Not clear why function call should be in string. As I can see, you have many cells that should fire one function with different params for each cell.
In this case I would do next:
TableCell detailCell = new TableCell();
detailCell.Attributes.Add("class", "detailCell");
detailCell.Attributes.Add("data-num", "4");
detailCell = new TableCell();
detailCell.Attributes.Add("class", "detailCell");
detailCell.Attributes.Add("data-num", "5");
And than, somewhere in js:
$(function() {
$(".detailCell").click(function(){
DoSomething($(this).data("num"));
});
})
class on table cell is needed in order to easily assign click handler to all detail cells, so you do not need to write something like:
$('#detailCell1').click(function () { DoSomething(4); });
$('#detailCell2').click(function () { DoSomething(5); });
This detailCell.Attributes.Add("data-num", "5"); allows to put number that should be used as a parameter for DoSomething. You can see it being taken in this row: DoSomething($(this).data("num")); jQuery.data function is being used. and this will point to an element being clicked.
$(function() {}) - this is a shorthand for jQuery.ready function. Using it you can guaranty that code inside that function will be executed when page is ready for use.
instead of first creating it as a string and then trying to evaluate that string you can simply create a function value (functions are object too in JS)
so instead of
var functionCall = 'DoSomething(4);';
$('#detailCell1').click(eval(functionCall));
do
$('#detailCell1').click(function(e){DoSomething(4);});
this creates a new function for every click. (In your case you could omit the e parameter, it's simply there to make any changes that requires it easier
if you have a set of parameters you are passing you can create a factory method
var doSomethingFactory = function(num){
return function(e) { DoSomething(num);};
}
$('#detailCell1').click(doSomethingFactory(4));
As per my understanding, you have to call different function with different arguments.To achieve this you are generating string and try to call those function by using eval() function. Let us do these as follows.
1.Just pass those functioncalls string as array, So that on load your javascript code look like as follows,
var functioncalls = ['DoSomething(1)','DoSomethingMore(1,2)','DoDifferent("hello world")'];
2.Then loop your function call array in javascript and assign them to different click event, To avoid complexity, I assume you selector are #detailCell0,#detailCell1,#detailCell2 and so on. Then your code look like as follows,
$(function(){
functioncalls.forEach(function(functioncall,index){
$("detailCell"+index).click(function(){
eval(functioncall);
})
});
})
Note: There are lot of ways to do this.
So I have a text box, where I add an onchange event of markAsException.
My javascript is -
function markAsException(recordID) {
//alert("Exception");
//mark exception column
document.getElementById("ctl00_cpMain_lblScrollException_" + recordID).innerText = "Exception";
document.getElementById("ctl00_cpMain_lblScrollException_" + recordID).style.color = "#FF0000";
document.getElementById("ctl00_cpMain_tdScrollException_" + recordID).style.backgroundColor = "#99CCFF";
//enable comments ddl and remove blank (first item)
document.getElementById("ctl00_cpMain_ddlCommentId_" + recordID).disabled = false;
document.getElementById("ctl00_cpMain_ddlCommentId_" + recordID).focus();
document.getElementById("ctl00_cpMain_ddlCommentId_" + recordID).options[0] = null;
}
What I want to do is, when a user changes the value in a textbox, to mark a column as "Exception", and then focus a drop down list where they have to chose the reason for the exception.
This is what happens.. If I am on that text box and change it, then tab, it tabs to the drop down list.
However, if I change the value and then simply click in another text box on the form, I don't focus the drop down list.
How would I accomplish that?
I would suggest using JQuery's change() function.
The advantage is that it will be more stable across different browsers.
Something like:
$('#<%= TextBox1.ClientID %>').change(function(){
// extract the recordID from the textbox - perhaps with an attribute?
markAsException(recordID);
});
My comment was getting longer so I'm expanding:
Take a look at the JQuery documentation for setting this up as the page finishes loading. If tb is the ID of your textbox your selector would be
$('#<%= tb.ClientID %>')
I would suggest you replace your code and use
tb.Attributes.Add("recordID", recordId.ToString());
This will add the ID you need onto the textbox tag. Once you're in the function I outlined above you can use the following selector to get the recordID in javascript
var recordID = $('#<%= TextBox1.ClientID %>').attr('recordID');
All together
$(document.ready(function(){
$('#<%= tb.ClientID %>').change(function(){
var recordID = $('#<%= tb.ClientID %>').attr('recordID');
if(recordID){
markAsException(recordID);
}
});
});
Is it possible to have a dropdown control with functionality that if there is no element in the dropdown im interested in I can just type it in myself ?
thanks for any help
Disclaimer: I know this question hasn't been tagged jQuery, but for future users searching i'll provide a start for a jquery solution.
Here's a relly simple start to a jQuery plugin to handle allowing dynamic options into a select box. An extra textbox and button is added to the DOM for each select element. Also an option is added to the bottom of the select list with text such as "add item...". Selected this option allows the user to type a new item in and add it to the select box.
Live example here: http://jsfiddle.net/8G6z3/1/
(function($) {
$.fn.freeEntry= function(options){
var settings = $.extend(
{},
{ //defaults
addItemText: 'add item...'
},
options
);
return this.each(function(){
var $this = $(this);
var $addItemOption = $('<option>' + settings.addItemText + '</option>');
$this.append($addItemOption);
var $addItemControl = $('<input type=text>').hide();
$addItemControl.insertAfter($this);
var $addItemButton = $('<input type=button value="add">').hide();
$addItemButton.insertAfter($addItemControl);
$addItemButton.click(function(){
if($addItemControl.val().length){
var $newOption = $('<option>' + $addItemControl.val() + '</option>');
$newOption.insertBefore('option:last',$this)
$this.val($addItemControl.val());
$addItemControl.val('');
}
$addItemControl.hide();
$addItemButton.hide();
});
$this.change(function(){
var $this = $(this);
if($this.val() == settings.addItemText){
$addItemControl.show().focus();
$addItemButton.show();
}
});
});
}
})(jQuery);
Usage: $('#mySelectBox').freeEntry( { addItemText: "Add a new item yo!"} );
This is not possible with the standard HTML select control, however you could use an HTML input textbox, which uses AJAX autocomplete to display a dropdown:
http://www.devbridge.com/projects/autocomplete/jquery/
Alternatively, you could have an "Other" option in the HTML select dropdown, which when selected, will display a TextBox control
You could have a text box near the drop down list with a submit button which appends html to the list section?
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.