Dynamically Enable/Disable a DropDownList based on CheckBox - javascript

I've got the following in a partial view, representing a row that is added dynamically:
<td>
<input asp-for="Id" class="form-control" />
</td>
<td>
<input asp-for="EnableDropDown1" id="EnableDropDown1Id" type="checkbox" class="form-control" />
</td>
<td>
<select asp-for="MyDropDown1" id="MyDropDownId1" asp-items="Html.GetEnumSelectList<MyEnum1Type>()" disable="disabled" class="form-control"></select>
</td>
<td>
<input asp-for="EnableDropDown2" id="EnableDropDown2Id" type="checkbox" class="form-control" />
</td>
<td>
<select asp-for="MyDropDown2" id="MyDropDownId2" asp-items="Html.GetEnumSelectList<MyEnum2Type>()" disable="disabled" class="form-control"></select>
</td>
I thought that maybe an onclick="EnableDropDown()" call attached to the CheckBox (that took a checkbox and a dropdown parameter) might do the trick, but it doesn't keep the state nor does the checkbox find the appropriate dropdown. I could loop through all the rows on a click and enable/disable dropdowns appropriately but this seems like a poor solution.
I've seen a fair few solutions out there but none of the simple ones work... either because they're not dynamic, or maybe it's down to the multiple checkboxes, or the fact it's an EnumSelectList and not a simple DropDown (Is there a difference?)..
I'm not too well-versed on javascript so I'm a bit lost with this one.

First, you are missing a "d" in the disabled attribute
Then if you are adding the row dynamically that means that the events are not added when the dom load, you can modify this behavior using a parent selector that already exists when the dom is rendered, also add some references using data-attributes between inputs and select make easier handle this
Try using the following code
$(".parent-class").on("change",".checkbox-class", function() {
var enabledDropdown = $(this).data("dropdown")
$(`#${enabledDropdown}`).removeAttr("disabled")
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="parent-class">
<tr>
<td>
<input asp-for="Id" class="form-control" />
</td>
<td>
<input data-dropdown="MyDropDownId1" asp-for="EnableDropDown1" id="EnableDropDown1Id" type="checkbox" class="form-control checkbox-class" />
</td>
<td>
<select asp-for="MyDropDown1" id="MyDropDownId1" asp-items="Html.GetEnumSelectList<MyEnum1Type>()" disabled="disabled" class="form-control"></select>
</td>
<td>
<input data-dropdown="MyDropDownId2" asp-for="EnableDropDown2" id="EnableDropDown2Id" type="checkbox" class="form-control checkbox-class" />
</td>
<td>
<select asp-for="MyDropDown2" id="MyDropDownId2" asp-items="Html.GetEnumSelectList<MyEnum2Type>()" disabled="disabled" class="form-control"></select>
</td>
</tr>
</table>

Related

HTML & JavaScript. Trying to target a text input from an adjoining anchor

I have an HTML table. On the table I have an input textbox. Next to it. (appended in the HTML) I have an anchor. All I want the anchor to do (at the moment), is get and set the value in the textbox.
Here is my (abbreviated code) HTML Code:
<tr>
<td class="t-Report-cell" headers="DEPARTMENT">
<input type="text" name="f02" size="20" maxlength="2000" value="" col_name="DEPARTMENT" class="u-TF-item u-TF-item--text" autocomplete="off" />
<td class="t-Report-cell" headers="DESCRIPTION">
<input type="text" name="f03" size="20" maxlength="2000" value="soup" col_name="DESCRIPTION" class="u-TF-item u-TF-item--text" autocomplete="off">
<a href="javascript:get_desc( $(this).closest('tr') );" class="a-Button a-Button--popupLOV">
<span class="a-Icon icon-popup-lov">
<span class="visuallyhidden">List</span>
</span>
</a>
<input type="hidden" id="fcs_0001" name="fcs" value="FB0D0992B787C5475D897B224F1FAE9D7547BC497FADE2E32B252FFAE2F31CE235225E0D645509C8E3576895FB814229B832CBF0BC11DA3F784FDE9BD5ADED86" autocomplete="off">
<input type="hidden" id="fcud_0001" name="fcud" value="U" autocomplete="off" />
</tr>
Notice I have an input type=text name=f03 with a value of "soup" (I've also given it another attribute to try and target it. (col_name="DESCRIPTION")
Then under it, I have an anchor which calls a JavaScript function and passes in the current row.
My simple function does the following:
function get_desc(thisRow) {
console.log(thisRow);
var desc = thisRow.find("input[name='f03']");
console.log(desc);
console.log(desc.val());
console.log(desc.text());
}
So it passes in the current row, looks for the input, then tries to get the value.
I can see on console.log that the correct selector is found, but nothing I do gets the value.
As I say, I have lots of JavaScript code in my app, so I've been staring at this wondering what I'm doing wrong
Some debugging shows that this is the window object when you use <a href="javascript:get_desc(this);", :
function get_desc(link) {
console.log(link === window);
}
click me
If you must use html attributes, then you can use onclick='get_desc(this):
function get_desc(link) {
thisRow = $(link).closest('tr')
var desc = thisRow.find("input[name='f03']");
console.log(desc.val());
}
<table>
<tr>
<td>
<input type="text" name="f03" value="soup">
click me
</td>
</tr>
</table>
Alternatively, embrace jquery events (or vanilla events)
$(".link").click(function() {
thisRow = $(this).closest('tr')
var desc = thisRow.find("input[name='f03']");
console.log(desc.val());
});
<table>
<tr>
<td>
<input type="text" name="f03" value="soup">
<a href="javascript:return false;" class='link'>click me</a>
</td>
</tr>
</table>
I used querySelector instead of find and value property of input.
function get_desc(thisRow) {
console.log(thisRow);
var desc = thisRow.querySelector("input[name='f03']");
console.log(desc.value);
}
<table>
<tr onclick="get_desc(this);">
<td class="t-Report-cell" headers="DEPARTMENT">
<input type="text" name="f02" size="20" maxlength="2000" value="" col_name="DEPARTMENT" class="u-TF-item u-TF-item--text" autocomplete="off" />
<td class="t-Report-cell" headers="DESCRIPTION">
<input type="text" name="f03" size="20" maxlength="2000" value="soup" col_name="DESCRIPTION" class="u-TF-item u-TF-item--text" autocomplete="off">
<a href="#" class="a-Button a-Button--popupLOV">
<span class="a-Icon icon-popup-lov">
<span class="visuallyhidden">List</span>
</span>
</a>
<input type="hidden" id="fcs_0001" name="fcs" value="FB0D0992B787C5475D897B224F1FAE9D7547BC497FADE2E32B252FFAE2F31CE235225E0D645509C8E3576895FB814229B832CBF0BC11DA3F784FDE9BD5ADED86" autocomplete="off">
<input type="hidden" id="fcud_0001" name="fcud" value="U" autocomplete="off" />
</tr>
</table>
instead of href use onClick attribute of anchor.
Try this;
<a href="#" onClick="javascript:get_desc( $(this).closest('tr') );" class="a-Button a-Button--popupLOV">

Cloning a tr and it is appearing at the top instead of at the placement of the tr defined

My tr is defined inside the table tag like this:
<table>
<tr>
<td>
<input type="text" name="customerid">
</td>
</tr>
<tr>
<td>
<div id="stlineitems">
<label for="stlineitems">Item(s)</label>
</td>
<td>
<div class="onlyleft">
<select name="get_Items" id="get_Items" class="selectItemsList" data-rule-required="true" data-msg-required="Choose Item">
<option></option>
</select>
</div>
<div class="moveboxleft">
<input type="text" class="inputwidth form-control rates_input" name="rate_items" data-rule-required="true" data-msg-required="Provide Rate or if not, provide 0 value" />
</div>
<br/>
<div class="nextitem">New Item
</div>
</td>
</tr>
</table>
Now, I am using the following snippet to create the cloned above code, all work but the placement is not right, I want it to be creating underneath the tr tag before this <div class="nextitem"> tag, not sure what I am doing wrong here
$('.createNewItemTag').click(function(){
var obj = $(this).parents('tr').first(),
clonedObj = $(obj[0].outerHTML);
clonedObj.find(".select2-container").remove();
clonedObj.find('.createNewItemTag').remove();
clonedObj.find('td').last().append("<a class='removeItem' href='javascript:void(0)';>Remove</a>");
clonedObj.find(".removeItem").click(function(){
$(this).parents('tr').first().remove();
});
console.log(obj);
obj.parents('table').append(clonedObj);
initSelect2ForNextItem(clonedObj.find(".selectItemsList").first());
});
If I understand your question, you want new cloned <tr> elements to be added BEFORE the element with the "new item" tag.
What we are going to do is utilize jQuery's built in .clone() method instead of doing it ourself. Once we have the cloned object we use your existing code to remove the New Item button and add the Remove button.
After we do that we'll utilize jQuery's .before() method to insert the new, cloned element before the original object. (You could use .after() if you wanted this to be inserted after the original object)
$('.createNewItemTag').click(function(){
var obj = $(this).parents('tr').first();
var clonedObj = obj.clone();
clonedObj.find(".select2-container").remove();
clonedObj.find('.createNewItemTag').remove();
clonedObj.find('td').last().append("<a class='removeItem' href='javascript:void(0)';>Remove</a>");
clonedObj.find(".removeItem").click(function(){
$(this).parents('tr').first().remove();
});
obj.before(clonedObj);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>
<input type="text" name="customerid">
</td>
</tr>
<tr>
<td>
<div id="stlineitems">
<label for="stlineitems">Item(s)</label>
</div>
</td>
<td>
<div class="onlyleft">
<select name="get_Items" id="get_Items" class="selectItemsList" data-rule-required="true" data-msg-required="Choose Item">
<option></option>
</select>
</div>
<div class="moveboxleft">
<input type="text" class="inputwidth form-control rates_input" name="rate_items" data-rule-required="true" data-msg-required="Provide Rate or if not, provide 0 value" />
</div>
<br/>
<div class="nextitem">New Item
</div>
</td>
</tr>
</table>
You may also want to clear the inputs of the original object so that it is empty after the clone is created. (or clear the inputs of the cloned object, up to you).
References:
https://api.jquery.com/clone/
https://api.jquery.com/after/
Try below code
Use obj.parents('table').find("tr:eq(0)").after(clonedObj); instead of obj.parents('table').append(clonedObj);
$('.createNewItemTag').click(function() {
var obj = $(this).parents('tr').first(),
clonedObj = $(obj[0].outerHTML);
clonedObj.find(".select2-container").remove();
clonedObj.find('.createNewItemTag').remove();
clonedObj.find('td').last().append("<a class='removeItem' href='javascript:void(0)';>Remove</a>");
clonedObj.find(".removeItem").click(function() {
$(this).parents('tr').first().remove();
});
//console.log(obj);
obj.parents('table').find("tr:eq(0)").after(clonedObj);
//initSelect2ForNextItem(clonedObj.find(".selectItemsList").first());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>
<input type="text" name="customerid">
</td>
</tr>
<tr>
<td>
<div id="stlineitems">
<label for="stlineitems">Item(s)</label>
</td>
<td>
<div class="onlyleft">
<select name="get_Items" id="get_Items" class="selectItemsList" data-rule-required="true" data-msg-required="Choose Item">
<option></option>
</select>
</div>
<div class="moveboxleft">
<input type="text" class="inputwidth form-control rates_input" name="rate_items" data-rule-required="true" data-msg-required="Provide Rate or if not, provide 0 value" />
</div>
<br/>
<div class="nextitem">New Item</div>
</td>
</tr>
</table>
Js Fiddle Demo : JSFiddle
Something like this?
$(document).on('click', '.createNewItemTag', function() {
var rw = $(this).parents('tr');
var ix = rw.index() +1; //remove +1 to insert above curr row
var obj= rw.clone();
obj.addClass('newcol').find('td:first-child').text('New Item');
$('table tr:nth-child('+ix+')').after(obj);
});
table{border-collapse:collapse;}
th,td{border:1px solid #ccc;}
.newcol td{background-color:palegreen;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tr>
<td colspan="2"><input type="text" value="customerid"></td>
</tr>
<tr>
<td>
<div id="stlineitems"><label for="stlineitems">Item(s)</label></div>
</td>
<td>
<div class="onlyleft">
<select>
<option>Options go here</option>
</select>
</div>
<div class="moveboxleft">
<input type="text" value="Provide Rate" />
</div>
<br/>
<div class="nextitem">New Item
</div>
</td>
</tr>
</table>
Notes:
(1) Switched to using .on() to allow newly added rows to be cloned

Angular JS regarding populating dynamic row data in form

Please see this screen shotI need some help. I want to populate dynamic table's row data into a form when i clicked on the particular row.When i try this html elements are repeating along with data when i click on the table rows, but i need like elements should not repeat only data should change. This is my template code
<table class="table2">
<tr>
<th>'Player'</th>
<th>Age</th>
</tr>
<tr ng-repeat=" usr in fc.saveData" ng-click="fc.fnRowClick(usr)">
<td>{{usr.player}}</td><td>{{usr.age}}</td>
</tr>
</table>
<div ng-repeat="data in fc.displayData track by $index">
<label for="field1">
<span>Name</span><input type="text" name="field1" required="true" ng-model="data.player"/>
</label>
<label for="field2">
<span>Age</span><input type="text" name="field2" required="true" ng-model="data.age"/>
</label>
</div>
This is my js code.
fc.displayData=[];
fc.fnRowClick = function(usr){
console.log(usr);
fc.displayData.push(usr);
console.log(fc.displayData);`
}
html name attribute is beeing duplicated during ng-repeat.
That may cause this problem.
Change:
<label for="field1">
<span>Name</span><input type="text" name="field1" required="true" ng-model="data.player"/>
</label>
to this:
<label for="field1{{$index}}">
<span>Name</span><input type="text" name="field1{{$index}}" required="true" ng-model="data.player"/>
</label>
Do the same for second label.

Angularjs selecting row of values and populating in a calling page

In my html I have code which dynamically adds rows when a button is clicked and on each row there is a button called "Add"
<form name="{{form.name}}"
ng-repeat="form in forms">
<div ng-repeat="cont in form.contacts">
Add
<input type="text" class="xdTextBox" ng-model="cont.ac"/>
<input type="text" class="xdTextBox" ng-model="cont.a_number"/>
</div>
<button ng-click="submit(form)">Submit</button>
<button ng-click="addFields(form)">Add</button>
<hr>
</form>
Than on my second page /edit i have following code that lists rows of values fetched.
<table>
<tbody ng-repeat="item in alllis">
<tr>
<td>
Select
</td>
<td>
<input type="text" ng-model="item.ac" />
</td>
<td>
<input ng-model="item.a_number />
</td>
</tr>
</tbody>
</table>
What I am trying to figure out is when I am on /edit and I select any row how do i populate back that row data on main page.
Please let me know from /edit page how do i go back to main page populating that row where Add button was clicked. Thanks
Here is the plunker for the first (Main) page.
http://plnkr.co/edit/VVUx2roDTrM9ob2uyZMv?p=preview

Toggle between a textbox and a select using PHP

I have a basic customer information form that I would like to make a little more interactive. The idea being if the user selects a country that is not USA or Canada the state Select turns to a state textbox. I'm sure this can be done with just PHP but have debated using jQuery but would like to avoid it if possible. Here is my form sample:
<tr>
<td>
<input name="city" type="text" id="city" value="<?= $this->aBillingProf['cCity']; ?>" />
</td>
<td>
<select name="state" id="state" style="width:218px;position:relative;top:-4px;">
<? $s = strlen($this->aBillingProf['cState']) == 2 ? strtoupper($this->aBillingProf['cState']) : strtoupper(stateTranslate($this->aBillingProf['cState']));
echo stateSelect('both',$s); ?>
</select>
<input name="state" type="text" id="state" value="<?= $this->aBillingProf['cState']; ?>" />
/*The Idea being only one of the above options is available depending on what is selected from the country select */
</td>
</tr>
<tr>
<td>
<label for="zip">Zip / Postal Code</label>
</td>
<td>
<label for="country">Country</label>
</td>
</tr>
<tr>
<td>
<input name="zip" type="text" id="zip" maxlength="6" value="<?= $this->aBillingProf['cZip']; ?>" />
</td>
<td>
<select name="country" id="country" style="width:218px;position:relative;top:-4px;">
<?= AffiliateStore::countrySelect($this->aBillingProf['cCountry']); ?>
</select>
<!-- <input type="text" name="country" id="country" value="<?= $this->aBillingProf['cCountry']; ?>" /> -->
</td>
</tr>
Basically what I do is to add a div containing the inputs I would need. In this case I would use a select boxes for US and Canadian states and a text input for other. Use the CSS diplay:none to collapse all divs except the one for the default selected country.
<div id="state_inputs">
<div id="us_states_div">
<!-- Select box for US states goes here -->
</div>
<div style="display:none" id="ca_states_div">
<!-- Select box for US states goes here -->
</div>
<div style="display:none" id="other_states_div">
<input type="text" name="other_states" />
</div>
</div>
Now assuming that your select box for the country has the id country_select:
<script>
document.getElementById("country_select").onchange = function() {
var country_select = document.getElementById("country_select");
var country = country_select.options[country_select.selectedIndex].text;
if(country == "USA") {
document.getElementById("us_states_div").style.display="block";
document.getElementById("ca_states_div").style.display="none";
document.getElementById("other_states_div").style.display="none";
} else if(country == "Canada") {
document.getElementById("us_states_div").style.display="none";
document.getElementById("ca_states_div").style.display="block";
document.getElementById("other_states_div").style.display="none";
} else {
document.getElementById("us_states_div").style.display="none";
document.getElementById("ca_states_div").style.display="none";
document.getElementById("other_states_div").style.display="block";
}
};
</script>
Once you've updated your PHP to output that markup, on the processing side you just look at the selected country and then use the value contained in the correct state input.
This can't be done with just PHP because it requires that you use client side scripting to determine when the event has been triggered. You could use PHP to rebuild the form, however, that would require a reload from the sever. It's much easier just to use JavaScript to handle the event and update the form.

Categories

Resources