C# ASP.MVC Get checkbox value using Html.EditFor and JavaScript - javascript

Just wondering, Imagine I have a checkbox like this:
<input type="checkbox" id="situationcontrol" name="situationcontrol">
I could check if this is checked or not by using this JavaScript code:
var situationcontrol = $("#situationcontrol").prop('checked');
Now I am wondering how this would work if you make a checkbox using #Html.EditorFor
Like this:
#Html.EditorFor(model =>Model.ServiceDeliveryMutableObjects.SituationControl)
I tried to change the same javascript code with the new generated ID
var situationcontrol = $("#ServiceDeliveryMutableObjects.SituationControl").prop('checked');
But that doesnt seems to work.
Any Idea how this would work?
Thanks
Edit: When I inspect element in browser when I use #Html.EditFor

EDIT
Didn't snap to that until you posted the rendered output. The . is not valid in HTML ids, so Razor uses underscores instead. So, the id you should be selecting is #ServiceDeliveryMutalObjects_SituationalControl, rather than #ServiceDeliveryMutalObjects.SituationalControl. Other than that, the rest of my original answer applies.
ORIGINAL
First, actually it's better to use:
$('#foo').is(':checked')
Now, as for using EditorFor, technically, this doesn't change anything. The id will obviously be based on the object graph, i.e. #ServiceDeliveryMutalObjects_SituationalControl, but nothing changes about the actual rendering of the HTML element. I emphasized "technically", here, because while that should be case, there's no default editor template that will actually render a checkbox input. The default is a text box, and a text box, obviously will not have a checked property. This can be corrected by either:
Use CheckBoxFor instead. That way, you're assured of getting an actual checkbox input.
Assuming this property is a boolean, you can create the view Views/Shared/EditorTemplates/Boolean.cshtml with something like:
#model bool?
#Html.CheckBox("", Model)
Then, EditorFor will use this template, and generate a checkbox input.
Finally, it may just be a typo in your question, but you want lowercase "model", not "Model", on the right side of your expression. In other words, it needs to match the left side of the lambda. I tend to avoid using model in these expressions, as not only is it more to type than needed, but you can easily get confused between "model" and "Model", especially with Intellisense's autocomplete. For example,
#Html.EditorFor(m => m.ServiceDeliveryMutableObjects.SituationControl)

You can change your code like this
Var situationcontrol = $("#ServiceDeliveryMutableObjects_SituationControl").prop('checked');
You need to remove .in Id of elements in mvc reazor view it's will convert '.' To '_' when we provide in elements name.

Related

How can I manipulate HTML elements which are added during the runtime?

The code im working on first makes a call to the database. Through this call, it is determined wether there are available workstations in the office or not.
If there are available workstations, "option" elements are added to a "select" element. This is achieved via jquery:
$('#idofselectelement').html(data)
Where "data" represents the markup to be inserted into the "select" element.
Now, my problem is that I'm trying to implement some code which checks wether your "favorite workstation" is available in the selected timeframe and then automatically preselects the respective workstation from the dropdownmenu in the "select" element. Everything is working so far, except for the selection of the workstation from the dropdown menu :/
The part of
I'm rather new to programming with javascript and the HTML DOM, so I'm not sure whether the fact that the options im trying to chose from are added during the runtime?
The code I've tried to manipulate the dropdown menu with is like this:
$('#idofselectelement').val(favoriteworkstation);
However, as I said, this doesn't work.
I've also already tried to output (console.log) the select element's length property right after the code which adds the markup with the available options has run.
But according to the output Im getting, the length is zero Oo
However, the dropdownmenu is definitely being created AND I can indeed manipulate it, but unfortunately not in the way I want to.
If I add an onclick event which sets the value of the respective select element, then the value in the select field indeed changes to the value specified in the event handler.
So I wonder why I can't have the favorite workstation preselected after the timeframe was chosen...
EDIT:
For further insight into the problem, I'm adding a bit more code here.
This is what the HTML Select element looks like BEFORE anything is added during the runtime:
<label for="#sitz">Sitz Nr.</label>
<select type="text" class="form-control" id="sitz" name="sitz" value="">
the markup which is added during the runtime
<option>workstationvalue</option>
<option>workstationvalue</option>
//and so on, depending on the situation...
This is a timing issue.
The js trying to find the element is faster than the actual add of the element to DOM.
Can you describe what you want to do? You might be able to do that before adding the element to DOM.
Editing before adding to DOM is possible if you convert your String to an jQuery object
var $jqueryObject = $(data);
$jqueryObject.find('.classYouSearch').val(value);
$('.whereToAd').html($jqueryObject);

Javascript change the value of innerHTML or innerText not working

I am working on a form (which comes from the Laserfiche Forms application) and I am trying to change the text on a button that currently reads "Auto Fill" which is very non-descriptive since I have 5 of those buttons.
A little backstory: My code used to work and then all of a sudden one day it doesn't and creates an error where the user can only see the "Submit" button and the title of the form, but as soon as I comment out the below code the form works again but then I have those non-descriptive buttons again.
Is something wrong with my code?
document.getElementById("lookup1573").innerHTML = "Fill Section";
On button inspection, I see something a little odd:
<button id="lookup1573" class="autofill" type="button vo="d">Auto fill</button>
You had a typo in the html:
type="button vo="d"
This is the correct way:
<button id="lookup1573" class="autofill" type="button">Auto fill</button>
Here is the full example:
https://jsfiddle.net/o2er21v0/
That is not a typo but a customer parameter of Forms.
So here is the easy way to use these kind of things with forms:
Firstly, give all of your elements classes. Whilst outside of using Forms it is recommended to use ID's to reference your elements, doing that with Forms will give you more work, tenfold.
To note about Autofill buttons: they only appear on lookups that you have enabled them on (unless you are using an old version of Forms) and will appear next to the last element in your lookup (if that makes sense).
To change the name of your autofill buttons you are going to have to do so after the page has loaded.
Below is example code to do just that, assuming that the element that has the Autofill button you have given it a class of "vendorName".
The "vo" is actually very useful as you can use it to easily interact with your field content in conjunction with your classes. In the below example I am changing what is in the field without having to go into the code and work out what the number of the id is. This makes any code you make more portable as you can then implement it in other projects, projects where you ID numbers will be different. This is so flexible that it does not matter if the "vendorName" element is a normal text input, multi-line text area or a drop down menu as that same piece of code will work the same.
4:
$(function() {
$( ".vendorName .autofill").text( "Fill Section" );
});
5:
$( ".vendorName [vo]").val( "A New Vendor Name" );
Forms already uses the jQuery library so this will work just fine. Remember to give all of your elements a class (I usually name it the same as the variable). You can also give them multiple classes by separating the classes with a space.

Thymeleaf+spring+Jquery dynamically added forms

Having troubles getting values from dynamically added dropdown in thymeleaf.
This is my first
<select th:field="${offer.offerItemList[__${iterationStatus.index}__].mapa}" class="form-control input-sm ofa">
<option value="0" >---Choose option---</option>
<option th:each="attribute : ${offer.offerProductAttribute}" th:value="${attribute.id}" th:text="${attribute.name}"></option>
</select>
Based on selecton from this dropdown i am generating another dropdown with code similar to this :
var options = '<select th:field="offer.list" class="form-control input-sm"> <option th:value="0">--Choose--</option>';
$.each(value.offerProductAttributeValuesList, function (index, value) {
options += '<option th:value="' + value.id + '">' + value.value+ '</option>';
});
options+= '</select>';
of.closest('tr').find('td:last').html(options);
Dom elements generate fine. Everything is ok but values are never submitted with the rest of input fields.
I have done this many times but with previously rendered
<select>
dropdown on the server side, and i would just appendTo() options, but in this case i cannot do that since i potentially have more than 20 dropdowns, based on clients selection from previous dropdown.
I hope i am being clear enough about my issue.
I am gonna answer my own question, since it took me quite some time to get around this problem, and my solution will probably help someone in the future.
The problem was : i had list of objects, and each one of those objects had another list of objects.
The problem is much easier to solve if you just render entire view from the backend (i was using thymeleaf). That way you can use thymeleaf expressions to map everything correctly
Like this :
First you gonna need for each to iterate over top level list
<tr th:each="item,iterationStatus : ${offer.offerItemList}">
You need to use iterationStatus to iterate over nested List, like this :
<select th:field="${offer.offerItemList[__${iterationStatus.index}__].mapa}">
This little piece of code __${iterationStatus.index}__ will basically use iteration index and you will end up with number for each iteration and rendered view will look like this offer.offerItemList[0].mapa, and 1 and 2 and so on.
this way values will be mapped correctly, BUT, if you want to add fields dynamically things get a bit more complicated.
There is jquery issue. Since jquery pretty much binds selectors when page is rendering, even if you write add another element, say <div class="temp">
and write perfectly good jquery function something like this $('.temp').on('click',function(){ console.log("clicked")});
nothing will happen since jquery didnt bind your newly created element to any select/event listener. The solution is to use (document).
$(document).on("click",".temp",function(){console.log('clicked');})
ok we have fixed front end issue, now newly created items work, but how do i tell spring to bind them to each object within list, which is part of another list? well you will have to use iteration index again :
When rendering the view you will need to save iteration index value in each element(using hidden fields)
Get value for each input field to jquery var like this : var iteration = $(this).closest('tbody').find('td:first-child').find('input').attr('value'); ofc this is path to where i have placed hidden input field, you will have to tell jquery where to look according to your structure.
You will simulate array and index numbers like this
var options = '<select name="offerItemList['+iteration+'].mapaValues">';
And the very last thing you need to be careful about is this : Say you have Object which you would normally send from controller like this model.addAttribute("offer",offer); object Offer has attribute, list of Products, so you would access that list with simple offer.productsList, but each product has list of AttributeValues. So final setup looks like this
offer.products[0].attributes[0].name products is an arrayList of objects of class Product, attributes is an arrayList of objects of class AttributeValues and name is a String. In order to let spring create object of class AttributeValues with information spring is receiving from dynamically(and non-dinamically) created forms from the frond-end, you will need to teach him how. If your new form with has input type="text" you are sending back String, so you will need to create a Custom constructor for
your class AttributeValues which will receive a String and which will tell Spring how to "construct" instance of that class with String.
finally create two constructors, one default and one with String as a value :
public AttributeValues(){}; and another for String public AttributeValues(String n){this.name = n;};
The problem you're most likely seeing here is that you're generating thymeleaf markup on the client-side.
Thymeleaf is a server-side templating language, so the browser (and hence the Javascript) will only ever see plain HTML coming back.
Here's a few approaches to consider:
submit the form each time to get new data in, which means no javascript is required
Output every possible dropdown into your HTML, and show/hide them as needed when the user selects options. Some fairly simple Javascript required, but as you mention - the page size may be pretty big
Add a JSON endpoint to your Spring webapp (see the spring #ResponseBody annotation) that will return just the data you need, then pull that JSON data in when the user selects a dropdown using something like jQuery.get()

passing hidden field values to javascript function

is it possible to get the value of the hidden field that is defined in the gridview to the javascript function so I have a gridview that has a linked button defined in it. If the user clicks on the link button, I am invoking a javascript function. I want the hidden field values in the javascript function.
also, I was wondering if it is possible to pass multiple values in one hiden field and then split them later in the javascript function.
any help will be appreciated. I don't want to go to code behind and then invoke the javascript function from there.
The first task is to determine a "suitable selector" for the hidden fields - this can be the ID (get via control.ClientID) of each individual hidden field or a more general selector like "all hidden fields in a particular div (with a particular ID)". Use <%= .. %> (or <%# .. %> in a data-binding context) to put this information into the actual HTML response.
The exact approach will vary - basically, whichever is easiest - for the task.
Then, using your favorite library or advanced browser with applicable selector support (it is easier to find good libraries)1, use the given selector. In jQuery, this might be similar to the following, where fn is the function to process all the values. The actual selector is the stuff in quotes:
fn(jQuery("#clientIdOfGridView input[type='hidden']"))
Which might be written in ASP.NET, which is how the appropriate element ID is injected:
fn(jQuery("#<%= gridView.ClientID %> input[type='hidden']"))
These will both pass a jQuery object representing the hidden field elements to the function. Then use val() and/or each() (see the jQuery documentation and other SO questions) for usage.
There are many questions relating to just jQuery and "selecting values", so this is entire "answer" is really to provide a lead on how to get started - Happy coding :)
1 While this can be done manually with "old-school" finding a element by ID and DOM traversal, I find it a waste of my time to do such a task manually. I like jQuery but there are alternatives. Use the existing wheels; they roll relatively fast.
you can specify as much values in one value-attribute of a hidden field as you like. You must make sure use a delimiter like "," or "#" which you can use in your function to split the string of values according to your needs.

How to hide a field in SharePoint Display Form based on the field name (jQuery)?

I have a SharePoint list with the following single line of text fields: Title, Year and Type or Location. I want to be able to hide the Type or Location table row in the default display form. I know that I should create a JavaScript script and put it in Content Editor web part inside DispForm.aspx.
I am not fluent with jQuery syntax, thus I need help with the code, i.e. I don't know how to reference the table row which contains Type or Location field and its value. Here's what I've done so far, but it doesn't work:
jQuery(document).ready(function($) {
$("input[title='Type or Location']").closest("tr").hide();
});
I know that the "input[title='Type or Location']" part is incorrect; at least I think it's that. Could anyone help me out? Thank you.
Try:
jQuery(document).ready(function($) {
$("h3.ms-standardheader:contains('Type or Location')").closest("tr").hide();
});
I am not sure why you want to use jQuery for that. In SharePoint, you can choose to make a field required, optional or hidden. In most cases, just switching to hidden will address your issue.
For the record, I would also try to avoid as much as possible the use of jQuery(document).ready, it might conflict with the SharePoint out of the box onload event. In your case it is not needed.
Update: here is a way to do this with jQuery:
$("td.ms-formlabel:contains('Type or Location')").parent().hide();
Try it this way:
jQuery(document).ready(function($) {
$("input[title='Type'],input[title='Location']").closest("tr").hide();
});
It depends what type of column Type ior Location is. If it's a Single line of text, then you're close. You should use a DOM inspector like IE's Developer Tools or Firebug to see what the actual title of the input element is.
If the column is a different type, then it's likely not an input element. Using the DOM inspector again, you can look at what elements make up the field control and decide on your selector from that.
Finally, remember that hiding things in script is not secure. A savvy user can turn off the script or otherwise change the script so that they can edit it. It all depends on your requirements.
// UPDATE //
Ah, you said DispForm. As was pointed out in another answer, there aren't any input elements in a DispForm. You need to correct your selector.
If its just the Default Display Form, How about just creating a view and making it default?
The syntax should be like this:
$("input[title='Type']").closest("tr").hide();
$("input[title='Location']").closest("tr").hide();
It will work.

Categories

Resources