How to use Jquery .on() method on multiple dynamic elements? - javascript

I am trying to attach an .on() click method to elements that I create dynamically. These elements each have a Bootstrap popover in them which acts as a menu with options for each element. The popovers are also created dynamically.
To make the menu work, I assign a unique number to each element and when an option from the menu is clicked, that unique number is extracted as a way to match the menu and it's options to the element. That way when I click the 'delete' option, it knows which element to delete.
However when I create multiple elements and try to extract the unique number, I only get the number of the first element.
HTML:
<div class="scenario-group" id="scenario-group-0">
<div class="scenario-list" id="scenario-list-0">Egypt</div>
<div style="display:none;" name="0" id="scenario-options-box-0" class="scenario-options-box" scn-box="0">
<button type="button" id="show-btn" class="scenario-option-btn btn-light" btn-box="0">Show</button>
<button type="button" id="rename-btn" class="scenario-option-btn btn-light" btn-box="0">Rename</button>
<button type="button" id="delete-btn" class="scenario-option-btn btn-light" btn-box="0">Delete</button>
</div>
<div>
<a tabindex="0" role="button" style="left:22px; top:2px;" name="0" class="scenario-btn" id="scenario-options-btn-0" scn-box-btn="0" data-toggle="popover" data-placement="left" data-trigger="focus" data-original-title="" title="">
<i style="color:#444444;" class="fas fa-caret-down" aria-hidden="true"></i>
</a>
</div>
<div class="scenario-group" id="scenario-group-1">
<div class="scenario-list" id="scenario-list-1">Nigeria</div>
<div style="display:none;" name="1" id="scenario-options-box-1" class="scenario-options-box" scn-box="1">
<button type="button" id="show-btn" class="scenario-option-btn btn-light" btn-box="1">Show</button>
<button type="button" id="rename-btn" class="scenario-option-btn btn-light" btn-box="1">Rename</button>
<button type="button" id="delete-btn" class="scenario-option-btn btn-light" btn-box="1">Delete</button>
</div>
<div>
<a tabindex="0" role="button" style="left:22px; top:2px;" name="1" class="scenario-btn" id="scenario-options-btn-1" scn-box-btn="1" data-toggle="popover" data-placement="left" data-trigger="focus" data-original-title="" title="">
<i style="color:#444444;" class="fas fa-caret-down" aria-hidden="true"></i>
</a>
</div>
JQuery:
$(document).on('click',".scenario-option-btn", function() {
var btnVal = $(this).text();
var btnID = $(this).attr("btn-box")
var scnID = $("#scenario-list-" + btnID + "").text();
})
The return values for btnVal are correct, however the value for btnID will always return 0 and I am struggling to see why.
Is this the correct way to assign event handlers to multiple dynamically created elements?
Any help would be appreciated. Thanks!

Related

Find closest id using jquery

im trying to get the closest id whena button is clicked to send it in an ajax request. But ive been struggling achiving so.
The HTML part is this one (cshtml)
<div id="modifyCar_#car.Id" class="modifyCar">
<!--Delete car button-->
<div>
<button type="button" class="btn btn-secondary btn-sm bg-danger" id="btnDeleteCar" name="btnDeleteCar">
<i class="fas fa-trash-alt"></i>
</button>
</div>
</div>
im trying to extract the #car.Id part
The JS part is this:
id: $(this).closest("div").find(".modifyCar").attr("id"),
Consider the following.
$(function() {
$(".btn").click(function() {
var myId = $(this).closest(".modifyCar").attr("id");
console.log(myId);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="modifyCar_#car.Id" class="modifyCar">
<!--Delete car button-->
<div>
<button type="button" class="btn btn-secondary btn-sm bg-danger" id="btnDeleteCar" name="btnDeleteCar"><i class="fas fa-trash-alt"></i></button>
</div>
</div>
.closest() can accept a selector, like a Class name. Your Code will stop at the Parent DIV Element, as that matches the closest "div" selector.

How to have several bootstrap buttons active at a time on one page?

I'm having trouble showing more than one button active to the user when using the bootstrap button class. I have two rows of buttons - I want the user to be able to select one value from each of the rows, and I want both selected buttons to show as active so that user can easily see the choices they selected. Currently, if the user selects one button, it becomes highlighted, but once they select another button from another row, the second button is then highlighted, but the first button no longer displays as active to the user.
So I have:
<div class="btn-group text-center">
<button type="button" class="btn btn-primary" value="row 1 choice 1" />
<button type="button" class="btn btn-primary" value="row 1 choice 2" />
</div>
<div class="btn-group text-center">
<button type="button" class="btn btn-primary" value="row 2 choice 1" />
<button type="button" class="btn btn-primary" value="row 2 choice 2" />
</div>
The user is directed to select one option from the first and second row and I just want both buttons to show they are active (by being indicating the darker color) once they are selected, instead of just one being able to be active at a time.
You first have to remove the class "active" from all the buttons and then add the "active" class to the pushed button:
<script>
$(".btn-primary").click(function () {
$(btn-primary").removeClass("active");
$(this).addClass("active");
});
</script>
You could just set the active class on them when they are clicked like this:
/* Latest compiled and minified CSS included as External Resource*/
#import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css');
body {
margin: 10px;
}
<div class="btn-group text-center">
<button type="button" class="btn btn-primary active" value="row 1 choice 1" />
<button type="button" class="btn btn-primary" value="row 1 choice 2" />
</div>
<div class="btn-group text-center">
<button type="button" class="btn btn-primary" value="row 2 choice 1" />
<button type="button" class="btn btn-primary active" value="row 2 choice 2" />
</div>
You need to toggle an active class on your buttons. Also there are problem around using a button element becuase they have default behavior when clicking them which messes the styling up. I have changed them to anchor tags and it works perfectly.
<div class="btn-group text-center">
<a class="btn btn-primary" data-value="row 1 choice 1"></a>
<a class="btn btn-primary" data-value="row 1 choice 2"></a>
</div>
<div class="btn-group text-center">
<a class="btn btn-primary" data-value="row 2 choice 1"></a>
<a class="btn btn-primary" data-value="row 2 choice 2"></a>
</div>
<script>
$(".btn-primary").click(function () {
$(this).toggleClass("active")
});
</script>
If you need to retrieve values from your anchor tags with javascript you can use html 5 data attribute as I have done:
html:
<a id="btn4" class="btn btn-primary" data-value="row 2 choice 2"></a>
Js:
$("#btn4").data("value")

How to make dropdown item a submit

My code below submit's perfectly as i want but the Add & Create new item in the bootstrap dropdown i need to be a submit, i've tried with javascript but then the html5 validation dosen't trigger. Is my only option to try and style the submit button like the bootstrap dropdown-item ?
$('btnWorkorder_Add_Create').click(function(event) {
event.preventDefault();
$('#WorkOrderFrm').append('<input type="hidden" name="btnWorkorder_Add_Create" value="1">');
$("#WorkOrderFrm").valid();
$('#WorkOrderFrm').submit();
});
HTML
<form id="WorkOrderFrm" name="WorkOrderFrm" action="/proc/WorkOrderFrm.php" method="post" autocomplete="off">
<div class="btn-group">
<div class="btn-group">
<button type="submit" id="BtnAdd" class="btn btn-custom btn-sm" name="btnWorkorder_Add">Add</button>
<button type="button" class="btn btn-custom btn-sm dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="" name="btnWorkorder_Add_Create" id="btnWorkorder_Add_Create">Add & Create New</a>
</div>
</div>
Why are you needing a dropdown if there is only one option?? Why not just use <input type='submit' value='Add And Create New' />
you are missing '#' tag. try this code and let me know if it is still not working
$('#btnWorkorder_Add_Create').click(function(event) {
event.preventDefault();
$('#WorkOrderFrm').append('<input type="hidden" name="btnWorkorder_Add_Create" value="1">');
$("#WorkOrderFrm").valid();
$('#WorkOrderFrm').submit();
});

Input Box Will Not Work in AngularStrap Select Custom Template

I created a custom template for the AngularStrap Select directive but I am unable to type inside of the textbox that I have added to the template for some reason. I would like to use this textbox to filter the list items.
Custom HTML Template (/dist/select.html)
The only thing that I added here from the default template was another <li> element that includes the textbox. Said another way, I basically copy & pasted the default template and added the <li> and <input> elements.
<ul tabindex="-1" class="select dropdown-menu" ng-show="$isVisible()" role="select">
<li>
<input type="text" class="form-control input-sm" ng-model="iconFilter" />
</li>
<li ng-if="$showAllNoneButtons">
<div class="btn-group" style="margin-bottom: 5px; margin-left: 5px">
<button class="btn btn-default btn-xs" ng-click="$selectAll()">All</button>
<button class="btn btn-default btn-xs" ng-click="$selectNone()">None</button>
</div>
</li>
<li role="presentation" ng-repeat="match in $matches" ng-class="{active: $isActive($index)}">
<a style="cursor: default;" role="menuitem" tabindex="-1" ng-click="$select($index, $event)">
<i class="{{$iconCheckmark}} pull-right" ng-if="$isMultiple && $isActive($index)"></i>
<span ng-bind="match.label"></span>
</a>
</li>
</ul>
HTML
This is the actual HTML that includes the call to the bs-select directive.
<button ng-if="path() === '/contacts/people'"
type="button"
class="btn btn-default btn-sm"
ng-model="selectedIcon"
data-html="1"
data-multiple="1"
data-template="/dist/select.html"
ng-options="icon.value as icon.label for icon in getIcons()"
bs-select>
Action <span class="caret"></span>
</button>

ng-repeat with in-line edit, how to make the first (or last element) have editmode = true?

I have an ng-repeat which loops over some items, and am using an editmode parameter to switch between a label and inputfield to let the user edit the value in-line.
Now I would like the functionality to be like this:
when the user presses the Add button, a new empty (or default) item is created, that has the editmode set to true (so that the input textbox shows with the save button, rather than the label with the edit button).
I have googled a lot about this but could not find a clear answer so far. :(
Code is as follows:
<div ng-repeat="todo in todos">
<span data-ng-hide="editMode">
{{ todo.name }}
</span>
<input type="text" placeholder="{{ todo.name }}" data-ng-show="editMode" data-ng-model="name" data-ng-required />
<button type="submit" class="btn btn-default btn-xs" data-ng-hide="editMode" ng-click="editMode = true">
<span class="glyphicon glyphicon-edit"></span>
</button>
<button type="submit" class="btn btn-default btn-xs" data-ng-show="editMode" ng-click="editMode = false; editTodo(todo._id)">
<span class="glyphicon glyphicon-save"></span>
</button>
<button type="button" class="btn btn-default btn-xs" ng-click="deleteTodo(todo._id)">
<span class="glyphicon glyphicon-remove"></span>
</button>
</div>
Thanks in advance
You could keep it simple by adding a separate input element outside of your ng-repeat.
Plunker: http://plnkr.co/edit/YDkzgtOSNpqDehnPkpZe?p=preview
Add another div element below your ng-repeat as below:
<div>
<button ng-show="!addNew" class="btn btn-sm btn-primary" ng-click="addNew=true">Add New</button>
<br>
<div ng-show="addNew">
<input type="text" ng-model="newTodo.name" ng-required />
<button type="submit" class="btn btn-default btn-xs" ng-click="addNewTodo()">
<span class="glyphicon glyphicon-ok"></span>
</button>
<button type="button" class="btn btn-default btn-xs" ng-click="resetNewTodo()">
<span class="glyphicon glyphicon-remove"></span>
</button>
</div>
</div>
Don't use editMode as scope variable. Use it as todo's object field (todo.editMode). Set it to true for new todo object.
The ngRepeat offers you $index - current position, $first, $last - so you can check against those to determine when you're on the first or when you reached the last element.

Categories

Resources