document.getelementbyid not recognizing razor element - javascript

In my index.cshtml file I have a razor element (#Html.EditorFor) that's a text box. Javascript isn't recognizing the element. If I change the element type to a non-razor syntax then javascript can see it. Am I missing some syntax here.
index.cshtml
<div class="jumbotron">
<h1>my application</h1>
#using (Html.BeginForm("Results", "Home", FormMethod.Post))
{
<div class="form-group">
//javascript can't see mainpagequery
#Html.EditorFor(model => model.SearchQuery, new { htmlAttributes = new { #class = "form-control", id = "mainpagequery" }})
#Html.ValidationMessageFor(model => model.SearchQuery, "", new { #class = "text-danger" })
//javascript can see mainpagequery in the non razor element here
<input type="text" class="form-control" placeholder="Search" id="mainpagequery">
</div>
<button type="submit" class="btn btn-default">Search</button>
}
Here is my javascript. If I use razor then 'mainpagequery' is underlines because it can't see it, if I use html then it's fine. I know I'm hitting my javascript because I see the alert message pop up.
$(document).ready(function () {
console.log("ready!");
alert("mainpage autocomplete function entered");
var input = document.getElementById('mainpagequery');
var options = {
types: ['(cities)'],
componentRestrictions: { country: "us" }
};
var mainpagequery = new window.google.maps.places.Autocomplete(input, options);
});

In case of #Html.EditorFor your id get overriden to model's property name.
If you find element using f12 you will find it as follows. (Notice id "SearchQuery124" I just renamed it to something)
So in your case in make change like
$(document).ready(function () {
console.log("ready!");
alert("mainpage autocomplete function entered");
var input = document.getElementById('SearchQuery').value;
console.log(input);
var options = {
types: ['(cities)'],
componentRestrictions: { country: "us" }
};
var mainpagequery = new window.google.maps.places.Autocomplete(input, options);
});

Try this
Instead of #Html.EditorFor use
#Html.TextBoxFor(model => model.SearchQuery, new { #class = "form-control" , id = "mainpagequery"})

Related

To Show/Hide <div> tag depending on the selection from previous drop down box

I have read many tutorials and many answers on stack overflow as well but it still does not work for me.Upon selecting an option (Yes)from drop down -> it should show the <div> tag otherwise <div> should be hidden.
Below is my code:
<h4>1. Does your school participate in the sponsored CAT4 scoring initiative?</h4>
#{
List<SelectListItem> listItems = new List<SelectListItem>();
listItems.Add(new SelectListItem
{
Text = "Yes",
Value = "True"
});
listItems.Add(new SelectListItem
{
Text = "No",
Value = "False"
});
}
<div class="form-group" id="PickOption">
<div class="col-md-10">
#Html.DropDownListFor(model => model.ParticipateInCAT4Scoring, listItems, "<----Select Yes or No---->", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ParticipateInCAT4Scoring, "", new { #class = "text-danger" })
</div>
</div>
<div id="OnYes" class="form-group" style="display:none">
#Html.Label("For what Grade levels?", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(m => m.GradeLevelsCAT4, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(m => m.GradeLevelsCAT4, "", new { #class = "text-danger" })
</div>
</div>
Below is the Script file which I am placing at bottom of View page:
#section Scripts{
<script type="text/javascript">
$(document).ready(function () {
$('#PickOption').on('change', function () {
if ($(this).val() == 'True') {
document.getElementById('OnYes').style.display = "";
}
else {
document.getElementById('OnYes').style.display = "none";
}
});
});
</script>
}
Your selector is not right, please make sure that you bind event on dropdown so add a class on dropdown
#Html.DropDownListFor(model => model.ParticipateInCAT4Scoring, listItems, "<----Select Yes or No---->", new { #class = "form-control pickerDropdown" })
Now bind the event on added class like this:
$('.pickerDropdown').on('change', function () {
PickOption is the ID of the wrapping div.
Replace #PickOption on this line with the ID or selector of the select box (usually auto-generated but you can specify.
$('#PickOption').on('change', function () {
Also since you're using jQuery, you can just do $('#OnYes').show();
https://api.jquery.com/show/

Validating Javascript Autocomplete

I have a web page with two TextBoxFor fields that utilize Javascript autocomplete. With one of the fields, ClientUser, the response includes an integer and a string. The integer is then compared with another integer field on the page, ClientID, and if they match, the string is used in the autocomplete suggestions. The other field's response, WorkmateUser, is a string list immediately usable in the autocomplete.
The controller is being hit and returning the correct total list, then the correct Url/field needing validation is chosen, but the list needing validation is undefined for the ClientUser autocomplete field needing validation. What is the most efficient way to compare an integer field on the page with an integer returned for the autocomplete list? Thanks in advance!
Razor:
<div class="row">
<div class="col-lg-12">
#Html.LabelFor(m => m.WorkmateUser, "Workmate To Add", new { #class = "control-label" })
#Html.TextBoxFor(m => m.WorkmateUser, new { data_autocomplete_url = Url.Action("GetWorkmates"), #class = "form-control" })
</div>
</div>
<div class="row">
<div class="col-lg-8">
#Html.LabelFor(m => m.ClientID, "Firm To Include", "--Choose Firm--")
#Html.DropDownListFor(m => m.ClientID, StaticCache.GetClients(Model.UserID), new { #class = "form-control" })
</div>
</div>
<div class="row">
<div class="col-lg-8">
#Html.LabelFor(m => m.ClientUser, "Client To Add", new { #class = "control-label" })
#Html.TextBoxFor(m => m.ClientUser, new { data_autocomplete_url = Url.Action("GetAllClients"), #class = "form-control" })
</div>
</div>
Javascript:
<script type="text/javascript" language="javascript">
$(document).ready(function () {
$('*[data-autocomplete-url]')
.each(function () {
var $url = $(this);
$(this).autocomplete({
source: $(this).data("autocomplete-url"),
response: function (data) {
if ($(this).data("autocomplete-url") == "/Message/GetAllClients") {
var aList = [];
for (var i = 0; i < data.length; i++) {//data.length is undefined!!!
if (data[i].ClientID == $("#ClientID").val()) {
aList.push(data[i].FirstName);
}
}
return bros;
}
else {
return data;
}
}
});
});
});
</script>
It's probably not the most elegant solution, but I ended up separating out the autocomplete call that needs validation into its own script and passing the additional variable into the controller to do validation on the back end. The following works:
Script:
<script>
$(document).on('keyup', '#ClientUser', function () {
var abID = $(this),
cID = $("#ClientID").val(),
cList = [];
$.ajax({
type: "GET",
url: '#Url.Action("GetAllClients", "Message")',
data: { term: abID.val(), clientID: cID },
success: function (data) {
for (var i = 0; i < data.length; i++) {
cList.push(data[i]);
}
},
error: function () {
alert("Client employeess could not be pulled.");
}
});
abID.autocomplete({
source: cList
});
});
</script>

How to check if PasswordFor is empty

I have TextBoxFor and PasswordFor in Razor, I want to check using js if both of them are filled with some data?
My code works, but only in case when there are two TextBoxes. How to make it works also for PasswordFor?
#Html.TextBoxFor(m => m.Login, new {#class = "form-control", #id="tekst1"})
#Html.PasswordFor(m => m.Password, new {#class = "form-control", #id="tekst2"})
<script type="text/javascript">
function disableButtons() {
$("input[type='submit']").attr("disabled", true);
}
function enableButtons() {
$("input[type='submit']").attr("disabled", false);
}
$(document).ready(function () {
disableButtons();
var $textInputs = $('input[type="text"],textInputs');
$('input').on('change', function () {
var anyEmpty = $textInputs.filter(function () { return this.value == ""; }).length > 0;
if (!anyEmpty) {
enableButtons();
} else {
disableButtons();
}
});
});
</script>
This Razor code:
#Html.TextBoxFor(m => m.Login, new {#class = "form-control", #id="tekst1"})
#Html.PasswordFor(m => m.Password, new {#class = "form-control", #id="tekst2"})
renders something like this to the browser:
<input type="text" class="form-control" id="tekst1">
<input type="password" class="form-control" id="tekst2">
(it likely also renders a label and possibly other attributes, but these are the important bits).
When you run the following code:
var $textInputs = $('input[type="text"],textInputs');
jQuery looks for elements like:
<input type="text" (any other attributes)>
<textInputs></textInputs>
As you can see, <input type="password" class="form-control" id="tekst2"> does not match either pattern. So, the only thing in $textInputs is:
<input type="text" class="form-control" id="tekst1">
If you've entered a value into that input, then after the filter:
$textInputs.filter(function () { return this.value == ""; }).length
will be equal to 0 and therefore anyEmpty will be false and enableButtons will be called.
If you want to find all input elements that are empty, regardless of their type attribute, change the line to:
var $textInputs = $('input');
Or, you could do all of this in a single function, like:
$(function() {
$(':input:not(:button):not(:submit)').on('change', function() {
$(':submit').prop('disabled', $(':input:not(:button):not(:submit)').filter(function(el) {
el.value === '';
}).length > 0);
});
});
Note that ':input:not(:button):not(:submit)' is a selector that will match all form elements except buttons, while ':submit' matches only submit buttons. See jQuery's documentation on form selectors.

Change EditorFor in time of change input

I want to change Editorfor that display already data from database when i change input
i will take output of input and split it and put result in 2 EditorFor
<input type="text" value="Set Date" id="reservationtim onchange=myFunction()>
#Html.EditorFor(model => model.StartDate, new { htmlAttributes = new { #class = "form-control" }, id = "startDate" })
#Html.EditorFor(model => model.EndDate, new { htmlAttributes = new { #class = "form-control" } , id = "endDate" })
and the function :
<script>
function myFunction() {
var date = document.getElementById("reservationtime").value;
var res = date.split("-");
model => model.StartDate = res[0];
document.getElementById("startDate") = res[0];
document.getElementById("endDate") = res[1];
}
</script>
You're trying to set the element reference itself to the value you want. Rather you need to set the value attribute of the element reference:
document.getElementById("startDate").value = res[0];
Also, it looks like you're trying to mix server-side and client-side code here. Remember that JavaScript is not processed until the document has already been processed by the server and returned to the client. Once you're client-side, all that exists is just the DOM, which is created by the browser based on the HTML document the server sent down. In other words, the fact that you used EditorFor or whatever is completely lost. All you have is the result (i.e. HTML) of that call to EditorFor.
You should first correct your HTML, as some attributes are not specified correctly.
<input type="text" value="Set Date" id="reservationtime" onchange="myFunction()">
#Html.EditorFor(model => model.StartDate, new { #class = "form-control" } )
#Html.EditorFor(model => model.EndDate, new { #class = "form-control" } )
I don't know why you are explicitly setting id for above two editors. they by default take property name as ID. so I would suggest following script for it.
<script>
function myFunction() {
var date = document.getElementById("reservationtime").value;
var res = date.split("-");
model => model.StartDate = res[0];
if(res.length>1) {
document.getElementById("StartDate").value = res[0];
document.getElementById("EndDate").value = res[1];
// if you still want to set ID properties instead of using default use following
// document.getElementById("StartDate").value = res[0];
// document.getElementById("EndDate").value = res[1];
}
}
</script>

Selecting dropdown value shows a Textbox, but doesn't stores a value passed in it

my view contains
<div class="col-md-3 ">
#{
List<SelectListItem> deformitylevel = new List<SelectListItem>();
deformitylevel.Add(new SelectListItem { Value = "hip", Text = "Hip" });
deformitylevel.Add(new SelectListItem { Value = "knee", Text = "Knee" });
deformitylevel.Add(new SelectListItem { Value = "ankle", Text = "Ankle" });
deformitylevel.Add(new SelectListItem { Value = "other", Text = "Other" });
}
#Html.DropDownListFor(model => model.DeformityLevel, deformitylevel, "--Select Level -", new { #class = "form-control", #onchange = "showdeformitytextbox()", id = "deformitydropdown" })
#Html.ValidationMessageFor(model => model.DeformityLevel, "", new { #class = "text-danger" })
</div>
<div class="col-md-3">
#Html.EditorFor(model => model.DeformityLevel, new { htmlattributes = new { #class = "form-control", id = "deformitytextbox" ,style= "display:none"} })
</div>
My function is
function showdeformitytextbox() {
if ($("#deformitydropdown option:selected").text() == 'Other') {
$("#deformitytextbox").show();
}
else {
$("#deformitytextbox").hide();
}
}
When I select "Other" in dropdownlist it stores 'other' in the database instead of storing a value which is entered in #Html.EditorFor.
What I'm forgetting Help!!
As mentioned by others, to make this cleaner, it would be best if you separated the model fields for the drop down and the textbox. Even if you get it to work using the below code, it will lead to more work if you have to return to the page with the other value selected. That said, the following does properly submit the expected value in the textbox. The key concept is to set the dropdown to disabled as you submit.
Assuming your form has an id of submitForm specified as follows:
#using (Html.BeginForm("someActionName", "someControllerName", FormMethod.Post, new { #id="submitForm"}))
Then the following code will ensure that the drop down doesn't submit its value by intercepting the form submission:
$("#submitForm").submit(function () {
if ($("#deformitydropdown option:selected").text() === "Other") {
$("#deformitydropdown").attr("disabled", true);
} else {
$("#deformitydropdown").removeAttr("disabled");
}
});
I would change the names of your current controls and make a hidden form element for DeformityLevel. Then set its value in javascript based on DropdownList and textbox change events.
***Something like this (jq not verified, just for illustration)
<select id="DeformityLevel_DDL">
<option></option>
<option></option>
<option></option>
</select>
<input type="text" id="DeformityLevel_TB" />
<input type="hidden" id="DeformityLevel" name="DeformityLevel" />
<script>
$(document).ready(function () {
$('#DeformityLevel_DDL').change(function () {
if ($(this).val() != 'other') {
$('#DeformityLevel').val(this.val());
}
});
$('#DeformityLevel_TB').on('change', function () {
$('#DeformityLevel').val($(this).val());
});
});
</script>
Well, your function only display the #deformitytextbox input, when the value entered there changes you should also update the model property.
If the form submits automatically on select change you should use preventDefault.
Try now with TextBox, your parameter for htmlAttributes is incorrect. Try:
<div class="col-md-3 ">
#Html.DropDownList("DeformityLevel", deformitylevel, "--Select Level -", new { #class = "form-control", #onchange = "showdeformitytextbox()", id = "deformitydropdown" })
#Html.ValidationMessage("DeformityLevel", "", new { #class = "text-danger" })
</div>
<div class="col-md-3">
#Html.TextBox("DeformityLevel", null, new { #class = "form-control", id = "deformitytextbox", style = "display:none;" })
</div>
<script>
function showdeformitytextbox() {
if ($("#deformitydropdown option:selected").text() == 'Other') {
$("#deformitytextbox").show();
}
else {
$("#deformitytextbox").hide();
}
}
</script>

Categories