How to bind jQuery event when ASP.NET MVC renders Model - c#

I have following HTML code under Requisition.cshtml
foreach (var item in Model.RequisitionWorks)
{
<tr>
<td><div class="radio"><label name="#string.Format("Option_{0}", item.OptionNumber)">#item.OptionNumber</label></div></td>
<td>
<div class="radio">
<label>#Html.RadioButton(string.Format("Option_{0}", #item.OptionNumber),
"0", #item.IsOptionChecked("0"), new { #class = "OptionClass", id = string.Format("Option_None_{0}", #item.ToothNumber) }) #MyModelEntities.Properties.Resource.None
</label>
</div>
</td>
And I generate lots of radiobuttons...
So I would like to bind some jQuery event at the moment of rendering that code.
$("#Option_None_" + optionNumber).change(function () {
});
I need it because I generate id of html tag on fly.
Is it possible to do?

Why not apply using the class of the option instead of an id?
$(document).ready(function(){
$(".OptionClass").change(function () {
});
});

You can do this by using the .on jquery method (http://api.jquery.com/on/). To accomplish this you would select your containing div and then set the onchange for the inputs within it.
$('div.radio').on('change', 'input', function() {});
Edit: it's a lot easier to do what you want to if you give the radio buttons a common class and use the above method. Generally it's not necessary use something unique like the id to attach the same event handler to each one.

Related

Render part of page on dropdown selection part 2

This is a follow on to similar question but taking suggestions into account.
Render part of page on dropdown selection
I have a chart on my main view which I would like to update partially when a dropdown selects different values.
The page renders correctly the first time, but when I select a new value in the dropdown, then I think the .submit script is failing in the script .submit() because when I put a break on window.submitAjaxForm it is never reached.
_PnlChart.cshtml
<img src="#Url.Action("CreateTraderPnlChart3")" width="600" height="600" align="middle" vspace="50" />
My mainview Index.cshtml:
<div class="w3-half">
<div id="ExportDiv">
#{ Html.RenderPartial("_PnlChart");}
</div>
#using (Ajax.BeginForm("GetEnvironment",
new RouteValueDictionary { { "Environment", "" } }, new AjaxOptions() { UpdateTargetId = "ExportDiv" }, new { id = "ajaxForm" } ))
{
#Html.DropDownList("PeriodSelection",
new SelectList((string[])Session["Periods"]),
(string)Session["Period"],
new
{ onchange = "submitAjaxForm()" })
}
</script>
<script type="text/javascript">
$('form#ajaxForm').submit(function(event) {
eval($(this).attr('onsubmit')); return false;
});
window.submitAjaxForm = function(){
$('form#ajaxForm').submit();
}
</script>
</div>
My controller:
public ActionResult PeriodSelection(string dropdownlistReturnValue) // dont know what dropdownlistReturnValue is doing?
{
Session["Period"] = dropdownlistReturnValue;
return PartialView("~/Views/Employee/_PnlChart.cshtml");
}
This line in your code,
eval($(this).attr('onsubmit')); return false;
I am not sure what you were intending to do here. But from your question, i assume you wanted to do a form submission. But that line will not submit the form. The expression $(this).attr('onsubmit') is going to return undefined as your form does not have an onsubmit attribute defined.
But you already have the form submit code in your other method (submitAjaxForm). So if you simply remove the $('form#ajaxForm').submit handler (apparently it does not do anything useful), your code will work. When you change the dropdown, it will make an ajax form submission.
But your form action is set to GetEnvironment action method. That means your ajax form submission will be to that action method. In your question you have a different action method which returns the updated chart content. It does not makes sense!
I personally prefer to write handwritten ajax calls instead of relying on the ajax action helper methods. The below is the code i would probably use (Except the dropdownlist code. read further)
<div id="ExportDiv">
#{ Html.RenderPartial("_PnlChart");}
</div>
#Html.DropDownList("PeriodSelection",
new SelectList((string[])Session["Periods"]),
(string)Session["Period"], new
{ data_charturl = Url.Action("PeriodSelection","Home")})
Now listen to the change event of the SELECT element.
$(function(){
$("#PeriodSelection").change(function(){
var v = $(this).val();
var url=$(this).data("charturl")+'?dropdownlistReturnValue='+v;
$("#ExportDiv").load(url);
});
});
You should consider using the a view model to pass the Dropdownlist data. Why not use the DropDownListFor helper method ? It looks much clean, Mixing a lot of C# code (See all the session casting and all.) makes it kind of dirty IMHO.

Generate jQuery functions dynamically mvc 4 razor

Currently, I am passing a list of object from controller to a view, and generate labels by the object's name.
What I am trying to do is to generate a jQuery function that will Dynamically create functions (toggle a form with relative lable id) for each label after being clicked.
The jQuery function is not working, I could not output the corrent jQuery function in the webpage...... Could you give me soem hints?
<table>
#foreach (var item in Model)
{
<tr>
<td>
#Html.Label(item.productName, new { #id = item.productId})
</td>
</tr>
}
</table>
<script type="text/javascript">
$(document).ready(function () {
#foreach (var item in Model)
{
$(#item.productId).click)(function({
//do something
}));
}
});
</script>
Thanks very much!
your JS syntax is wrong, for starters. What you want to do is to give all those labels a class name (such as product_lbl) or a data attribute (if you don't like semantic class names) such as product-lbl. This way you don't have to do a second loop to add click event handlers. You'll only need one, like so:
$('.product_lbl').on(
'click',
function() { /* Do something for whichever label was clicked */ }
);
OR
$('[product-lbl]').on(
'click',
function() { /* Do something for whichever label was clicked */ }
);

Div elements on click fires for the first element only

I am listing my data in an ItemTemplate.Then inside the ItemTemplate, i have two div tags as follows:
<ItemTemplate>
<div id="contentdiv">
<h4 id="titleresult"><%# Server.HtmlEncode(Eval("Name").ToString())%></h4>
</div>
<div id="showclick" class=hideAll>
<p class="brief"><%# Server.HtmlEncode(Eval("LegalName").ToString())%></p>
<p class="brief"><%# Server.HtmlEncode(Eval("FirstName").ToString())%></p>
<p><%# Server.HtmlEncode(Eval("LastName").ToString())%></p>
</div>
</ItemTemplate>
Then i have the css to define the hideAll class so that when the page loads, the data in this div tag is hidden until the user clicks on the contentdiv link.
.hideAll { display:none }
.displayAll { display:block; top:0px}
Then finally i have the javascript part for firing the click event.
<script type="text/javascript">
function showResults(UserID) {
var contentdiv= document.getElementById('contentdiv');
var showclick = document.getElementById('showclick');
<%
long id =0;
DataAccess dataAccess = new DataAccess();
Data = dataAccess.GetCounterParty(id);
%>
var UserID = <%=dataAccess.GetCounterParty(id) %>
contentdiv.style.visibility = "visible";
$(showclick).removeClass('hideAll');
}
</script>
The UserID is the id of every element in the list. The problem is, the click affects only the first element no matter which other element i click on the list.
In html id is used to refer to one element.
If you use it multiple times the browser would default to the first element.
You should use a class selector. Something like:
$(".contentdiv").click(function(){
$(this).next().removeClass('hideAll');
});
Here is a working example. I used toggleClass though, it seems more appropriate to me.
An id is a unique identifier, you cannot have two or more things on the same page with the same identifier and expect things to work properly. Make your identifiers unique, and bind to the click event using a class selector instead.
you should use class instead of id, id are unique, which only exist in 1 page, class can exist in multple div
some idea for u
html
<div class="showclick hideAll">
script
$('.showclick').on('click', function(){
$(this).toggle(); //toggle to show or hide, can be any element u want to toggle instead of this
});

Treeview (Kendo UI) with TextBox on the same page best practices in MVC4?

Let's say I have a view with Kendo treeview bounded to remote data source.
#(Html.Kendo().TreeView()
.Name("schemas")
.DataTextField("name")
.DataSource(dataSource => dataSource.Read(read => read.Action("Schemas", "Forms")))
.Events(events => events
.Select("onSelected")))
So the treeview just makes a call to the Schemas action in my FormsController
Also on the same page I have a form, which is simply the textbox and a button to submit the form
#using (Html.BeginForm("Load", "Forms", FormMethod.Post))
{
<div id="rootNode">
#Html.TextBox("rootElementName")
#Html.Button("next")
</div>
}
So I am just wondering what is the best way to handle user input and pass it to the the Load action of the FormsController? The user should select one of the options in the treeview and enter the value into textbox.
Or should I create some sort of viewmodel for my view with all my nodes inside + two additional fields for the textbox input and selected node?
I would take out the form elements, leaving:
<div id="rootNode">
#Html.TextBox("rootElementName")
#Html.Button("next")
</div>
The following js, this will pick up the tree item id on select.
The second function will call your Form controller action with the parameters.
<script>
var selectedNodeid;
//get the tree selected item id
function onSelected(e) {
var data = $('#schemas).data('kendoTreeView').dataItem(e.node);
selectedNodeid = data.id;
}
//button on click event
$(document).ready(function () {
$("#next")
.bind("click", function () {
//get parameters then pa
var id = selectedNodeid;
var rootElementName = $('#rootElementName).val()
$.ajax({
url: "Form/Load",
data:{id:id,rootElementName:rootElementName},
success: function () { }
});
}
})
</script>
I haven't tested this but it should be close.
I look forward to someone adding a better approach.

Best way to display a group/selection of radiobuttons from the choice of a single radiobutton?

I have a form which for some questions would ask if something was included and if it isn't to supply a reason.
So I need a radio button which records to the database it's value like normal which I have setup with a RadioButtonFor and if "No"(false) is selected then a group/list of other radiobuttons will display.
Ofc this is just the ideal solution if this method isn't feasible then another solution would be to maybe a if statement in the controller so that if that main radiobutton has a value of "Yes"(true) then it would set the values of x, y and z radiobuttons to "No"(false) when it records the form to the database.
These are the 2 ideas I have on how to get the same end result but for the 1st idea I think the easiest way to perform it's function would be in jquery which I'm fairly new at so would struggle to come up with how to do it
For the 2nd idea it's 1 not ideal and 2 I'm not sure how I would then reference those radiobuttons/code the if statement to do said task.
Any other ideas would also be welcome but hopefully with help on how to implement them.
Well, this may sound overkill, but I would go with both solutions. You need the javascript script side code to do it right from a presentation standpoint - and you need the server-side code to do the validation right too.
If you implement only the client-side validation, how the system will behave if a browser has no support to javascript, or if it is just disabled? You cannot take javascript support for granted...
OTOH, you would offer a best user experience if you added that client-side functionality you're talking about...
And about your doubt of how to do the server-side validation: that's easy with ASP.NET MVC - on load, just set the same ViewData entry/ViewModel property that you have read during post.
Edit So let's talk about a complete solution.
Again, I'm not sure I understood what you need here. You're talking about radiobuttons, but you also seem to think you'll be able to control them individually (many radios binding to many fields). That's not usually the case - a group of radiobuttons is normally bound to the same field, with each radiobutton meaning a different value (so exactly like a single dropdown list). Of course, that does not mean your database must behave in the same way...
See this example:
<% using(Html.BeginForm("HandleForm", "Home")) { %>
Select your favorite color:<br />
<%= Html.RadioButton("favColor", "Blue", true, new { id = "rbColorBlue", class = "favColor" }) %> Blue <br />
<%= Html.RadioButton("favColor", "Purple", false, new { id = "rbColorPurple", class = "favColor" })%> Purple <br />
<%= Html.RadioButton("favColor", "Red", false, new { id = "rbColorRed", class = "favColor" })%> Red <br />
<%= Html.RadioButton("favColor", "Orange", false, new { id = "rbColorOrange", class = "favColor" })%> Orange <br />
<%= Html.RadioButton("favColor", "Yellow", false, new { id = "rbColorYellow", class = "favColor" })%> Yellow <br />
<%= Html.RadioButton("favColor", "Brown", false, new { id = "rbColorBrown", class = "favColor" })%> Brown <br />
<%= Html.RadioButton("favColor", "Green", false, new { id = "rbColorGreen", class = "favColor" })%> Green
<%= Html.RadioButton("favColor", "Other", false, new { id = "rbColorOther", class = "favColor" })%> Other
<div id="divOtherColorText" style="display: block">
Describe the color you want here:<br />
<%=Html.TextArea("otherColorText", new { id = "taOtherColor" }) %><br />
</div>
<% } %>
This will bound to a single controller parameter, favColor, with a default value of "Blue". See that, for convenience, we're assigning a distinct client-side id for each radiobutton (rbColorBlue, rbColorGreen and so forth). That means that you'll be able to treat each radiobutton individually in your jQuery code, even if they represent a single value to the server-side controller.
Talking about the server-side code, that's how the action will look like:
public class HomeController : Controller
{
public ActionResult HandleForm(string favColor, string otherColorText)
{
// Add action logic here
// If you want to have a separated field for your database,
// just do something like that:
MyDbFacade.BlueColorField = (favColor == "Blue");
MyDbFacade.GreenColorField = (favColor == "Green");
...
return View();
}
}
(Of course, you could also work with a ViewModel, but I'll not talk about that option here.)
Back to client-side. Let's suppose you don't want to show taOtherColor, unless the user selects the rbColorOther radiobutton. The jQuery code would be something like this:
$(document).ready(function() {
// If user selects any radiobutton:
if ( $('#rbColorOther:checked').length > 0) {
$("#divOtherColorText").show();
} else {
$("#divOtherColorText").hide();
}
});
I guess that would be it. Let me know if I have missed something... :-)
I would go with your first solution. Render both groups of radio buttons on the page but hide the second group with css. Then set some onclick events on the radio buttons in your first group to show/hide the second group depending on which one is clicked.
I think it is easier to just write the html for the radio buttons by hand because of the onclick handlers you are writing, but you could probably manage it using RadioButtonFor as well.
So your yes/no would look like this:
<input type="radio" name="yesNo" id="yes" onlclick="$('#other-options').hide();' value='true' <%: Model.YesNo ? "checked='checked'" : "" %>/><label for='yes'>Yes</label>
<input type="radio" name="yesNo" id="no" onlclick="$('#other-options').show();' value='false'<%: !Model.YesNo ? "checked='checked'" : "" %>/><label for='no'>No</label>
Your other options would look like this:
<div id='otherOptions' <%: Model.YesNo ? "style='display: none;'" : "" %>>
<input type="radio" name="XYesNo" id="xyes" value='true'/><label for='xyes'>X Yes</label>
<input type="radio" name="XYesNo" id="xno" value='false'/><label for='xno'>X No</label>
<input type="radio" name="YYesNo" id="yyes" value='true'/><label for='yyes'>Y Yes</label>
<input type="radio" name="YYesNo" id="yno" value='false'/><label for='yno'>Y No</label>
<input type="radio" name="ZYesNo" id="zyes" value='true'/><label for='zyes'>Z Yes</label>
<input type="radio" name="ZYesNo" id="zno" value='false'/><label for='zno'>Z No</label>
</div>
In your action method ignore any x,y,z values if the first YesNo was true :
if(model.YesNo){
//persist false values for x,y,z
} else {
//check model for values of x,y,z
}
Well I figured out the simpliest way to get the controller to sort out the validation which was
if (wd.AppTher == true)
{ wd.AppTherRea = 0; } this is the example for a drop down and for another radiobutton it would be instead of "0" or whatever value u want for the drop down for it to be "false" or if you want/have multiple options with int at the db field type then you just set your N/A or w/e value as the = too, for multiple RB or DDL then just add more in between { and }, wd was the value assigned to represent the table and otherwise a viewmodel value could be used.

Categories