Capture value of Textbox when OnChange is defined in the textbox - c#

I have a dynamically generated grid with x number of textboxes that will be in it. As each textbox is generated, I give it an OnChange event that is a set function.
Html.TextBox(... new { #onchange = "ChangeItemQuantity(" + vm.ID + ", " + fk.id + ")" ...
So when it's rendered, it looks like this:
<input ... type="text" onchange="ChangeItemQuantity(1939, 3)" />
Then, in the script section:
function ChangeItemQuantity(ItemId, ForeignKeyId) {
...
}
In the ChangeItemQuantity() function, how would I also capture the new value of the textbox? I don't really want to use an id on the textbox, because it is part of a grid with many textboxes.
Should I pass it in as a parameter? If so, what would the syntax be of the code that renders the textbox?
Or, is there a way to capture is inside the javascript function?
Thanks!

If you want to store data in the html element why not use data- attributes?
Set them like so
#Html.TextBox(.... new { #class="someClass" data-vmId="vm.ID", data-fkId="fk.id" })
Then set a listener on that class
$('.someClass').change(function() {
var value = $(this).val();
var vmid = $(this).data('vmid');
var fkid = $(this).data('fkid');
}

Related

How do I get input element id from placeholder text?

I'm using Selenium and C#.
I'm trying to find an element id for an input field by the already typed in text (the elements id is autogenerated randomly for every instance) and then type a new text.
My failed attempt:
public void SetValues(){
var textField = driver.FindElement(By.XPath("//input[contains(text(),'my_text')]"));
((IJavaScriptExecutor)driver)
.ExecuteScript("window.scroll(" + textField.Location.X + "," + (textField.Location.Y - 200) + ");");
textField.sendKeys("some_text");
}
How can I make my code to work?
Place holder is an html attribute so you can use #placeholder, check the following line:
var textField = driver.FindElement(By.XPath("//input[#placeholder='my_placeholder']"));
Edited:
There is no way to get the text entered manually if javascript assigns the value to an attribute.

Bind to list ASP.NET MVC dynamic jQuery index

I have a set of list elements, that I create dynamically. Each of these list elements, contains an input text, whose value I want to pass to the controller.
HTML
<ul id="list"></ul>
<button id="add">Add</button>
<script>
var counter = 1;
$('#add').click(function () {
var text = '<input type="text" name="(what should I put here?)"></input>';
var li = '<li>' + text + '</li>';
$(li).appendTo('#list');
counter++;
return false;
});
</script>
View Model
public IEnumerable<string> list {get; set;}
...
How can I bind those values to my ViewModel implicitly? I have tried to use the counter variable to assign a name to each created element (like list[counter]), but on the controller side the list variable on my ViewModel still comes empty.
First I would base your counter on the amount of li's within your un-ordered list with:
$('#list > li').size()
Then in order to keep the model binder happy pre-fix your property with list:
'<input type="text" name="list[' + counter + ']"></input>'
The full code then becomes:
$('#add').click(function () {
var counter = $('#list > li').size();
var text = '<input type="text" name="list[' + counter + ']"></input>';
var li = '<li>' + text + '</li>';
$(li).appendTo('#list');
return false;
});
jsFiddle
Please note, you will have to change your view model property to an IList or List for indexing to work too:
public IList <string> list {get; set;}
Because your collection is for value type (string) only, then you can simply use
$('#add').click(function () {
var text = '<input type="text" name="list"></input>';
....
});
It is only necessary to include indexers when the property is a member of a complex object.
If you do include the indexer, it must start at zero and be consecutive (unless you also include a special hidden input for to identify the indexer). Your attempt at using list[counter] failed because the value of counter is initialized to 1 (it would have worked had you initialized it to var counter = 0;)

Why is my element not seen as equating to itself?

I've got an html input text element created like this in C#:
boxIndex1 = new TextBox()
{
CssClass = "dplatypus-webform-field-input indexcell",
Width = TEXTBOX_WIDTH,
ID = "boxIndex1foapalrow2"
};
...and this jQuery to respond to the blur event of "boxIndex1foapalrow2" and its cousins ("boxIndex2foapalrow3", "boxIndex3foapalrow4", etc.):
$(document).on("blur", '.indexcell', function (e) {
var $currentindexcell = $(this);
if ($currentindexcell == $('[id$=boxIndex1foapalrow2]')) {
alert('index cell 1 exited'); // testing
}
});
I stepped through it, and the element assigned to $currentindexcell when I tab out of "boxIndex1foapalrow2" seems to be what I'm expecting:
<input name="ctl00$ctl24$g_5f3fedca_19f7_4bc3_b84e_efbef0c48a33$ctl00$boxIndex1foapalrow2" type="text" id="ctl00_ctl24_g_5f3fedca_19f7_4bc3_b84e_efbef0c48a33_ctl00_boxIndex1foapalrow2" class="dplatypus-webform-field-input indexcell" style="width:88px;">
...but the alert is not showing/the if condition equates to false. Why? It seems to me that the value of $currentindexcell in this instance does equal $('[id$=boxIndex1foapalrow2]'), but why doesn't it seem that way to the Javascript execution engine?
Two jQuery objects that contain the same set of elements are not equal. To test whether your jQuery object matches a selector, use .is():
if ($currentindexcell.is('[id$=boxIndex1foapalrow2]')) {
If you really wanted to check for equality, you should compare the actual elements (not the jQuery objects that hold them):
if (this == $('[id$=boxIndex1foapalrow2]')[0]) {

setting the value of textbox equal to address bar in MVC4?

How can I set the Textbox's value equal to address bar?
for example :
localhost:28362/?f=Ava
when we click on a button the value of textbox must set to : Ava
?
Try this, Add Query String Jquery Js(querystring-0.9.0-min.js) in solution
$("#ButtonId").click(function(){
$("#textBoxID").val($.QueryString("f");)
});
Here is Javascript function to get query string value:
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
Then you need to assign this value to a textbox. I would use jQuery:
$(function(){
$("#myTextBoxID").val(getParam("f"));
})
If you want a solution that uses MVC4 rather than JavaScript, define your controller method as:
public ActionResult Index(string f) {
return View(f);
}
In your view, you would then use one of:
#model string;
#Html.TextBoxFor(Model)
or
#model string
<input type='text' value='#Model' name='myValue' />
Obviously this is vastly oversimplified, but should give you a good starting point.

Pass hidden ID when textbox is changed

I have multiple textboxes, every textbox has a related hidden field, the hidden field's ID is a concatenation of a string with the model's ID (ex: "FormState25")
How can I pass the ID of a hidden field when a textbox being changed? I'm using the following code to detect textbox change:
$("#body-content-container").on('change', 'input[type="text"]', function () {
$("#FormState").val('dirty');
});
You can add custom attributes to the textbox tag itself that includes the Id of the hidden field, for example:
In View
#Html.TextBoxFor(model => model.Name, new { HiddenFieldId = "FormState" + Model.Id })
This way when a textbox get changed you can get the Id of the hidden field you already use to store whatever you want, and then modify the javascript to handle that hidden field's Id, like this:
Javascript
$("#body-content-container").on('change', 'input[type="text"]', function () {
var hiddenId = $(this).attr("HiddenFieldId");
$("#" + hiddenId).val('dirty');
});
The javascript will get the HiddenFieldId attribute of the corresponding hidden field from the textbox and change it's value. Try this and let me know..
You can use this to reference the element on which the anonymous function is defined, e.g.:
$("#body-content-container").on('change', 'input[type="text"]', function () {
$("#FormState" + this.attr('id')).val('dirty');
});
try this:
$("input[type=text]").click(function(){
var hiddenId = "FormState" + $(this).attr("Id");
var hiddenField = $("#" + hiddenId);
hiddenField.val("dirty");
});
EDIT:
if your hidden field rendered just after your inputbox then you can do the following :
$("input[type=text]").click(function(){
var hiddenField = $(this).next();
hiddenField.val("dirty");
});
hope this could help.
Here's another trick which I've used in the past. Enclose the two related input fields in a div (or other) element. Then use the fact that the text field and the hidden field are siblings to select the correct hidden field. Perhaps something like this (NOTE: I have not tested this example):
<div id="someId">
<input type="hidden" value="unchanged" />
<input type="text" value="some data" />
</div>
<script type="text/javascript">
var hiddenInput = $('#someId input:first')
var textInput = $('#someId input:last')
textInput.on('change', function() {
hiddenInput.val('modified');
});
</script>

Categories