Issue with data-th-id - javascript

I have a button that leads to a modal view. I try to intercept the value with JS.
It works like this:
<button type="button" class="btn btn-outline-primary btn-sm"
data-toggle="modal" data-target="#myModal" data-person-id="something">
Edit
</button>
JaveScript:
var bookId = $(e.relatedTarget).data('person-id');
It doesn't work like this:
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal"
data-target="#myModal" data-th-id="${person.getId()}">
Edit
</button>
JS:
var bookId = $(e.relatedTarget).data('id');
or
var bookId = $(e.relatedTarget).data('th-id');
var is undefined it says.
Since I use Thymeleaf I need to catch the value with data-th-id.
Any idea how to get the value
Complete JS
$('#myModal').on('shown.bs.modal', function (e) {
$('#myInput').focus();
var bookId = $(e.relatedTarget).data('id');
alert(e.relatedTarget.nodeName);
alert(bookId);
});

data-person-id="something" is a data attribute, and is accessed with $('...').data('person-id').
data-th-id="${person.getId()}" isn't a data attribute. It's just a different way of saying th:id, which outputs the id="..." attribute of a tag. You can't use jQuery's .data() method on non-data attributes, instead you use attr() -- $(e.relatedTarget).attr('id');

Related

Accessing dynamically created variable in onclick

I have a foreach loop, enumerating my models to create a table. In this table, i need to have an edit button for each model where i call a javascript function to show a modal.
I need to pass the model into the javascript function, but i can't get this to work. I've worked out how to dynamically create the variables, but not how to use it as input.
Right now, it's just hardcoded to use 'department1', which is just the first created. I need toggleManageDepartmentModal to be called with (department + #department.Id)
Creating the table
#foreach (var department in Model.PaginatedDepartments())
{
<tr>
<td>#department.Name</td>
<td>#department.Description</td>
<td class="min">#department.Created.ToLocalTime().ToString("dd-MM-yyyy")</td>
<td class="min">
<div class="text-nowrap">
<script>
//Dynamically create variables for each department
eval('var department' + #department.Id + '= #Json.Serialize(department);');
</script>
<button type="button" class="btn btn-secondary btn-sm" onclick="toggleManageDepartmentModal(department1)">
<span class="fa-solid fa-pen-to-square" aria-hidden="true"></span>
Rediger
</button>
</div>
</td>
</tr>
}
Javascript function to show modal
function toggleManageDepartmentModal(department) {
var model = {
department : department,
controller : 'Admin',
action : 'ManageDepartment'
};
$.ajax({
type: "Post",
url: "/Modals/ShowManageDepartmentModal",
data:model,
success: function (data) {
$("#loadModal").html(data);
$('#modal-manage-department').modal('show')
}
})
}
I would like to do something like this:
<button type="button" class="btn btn-secondary btn-sm" onclick='toggleManageDepartmentModal(Eval("department" + #department.Id))'>
<span class="fa-solid fa-pen-to-square" aria-hidden="true"></span>
Rediger
</button>
I am not exactly familiar with the tool (a templating engine?) you are using to build your HTML, but I will try to help.
Traditionally, before the JS framework takeover, the way to attach data to HTML elements was to use data-attributes. In your case, I would use something like data-department. I would dare to say that it's much better way then using script tags + eval()
The simplest way would be to attach the data to the button. Probably like a serialized JSON:
<button data-department="#DataGoesHere" type="button" class="btn btn-secondary btn-sm">
Rediger</button>
How about the onclick function? You can get the button's reference by using this argument:
<button onclick="toggleManageDepartmentModal(this)" data-department="#DataGoesHere" type="button" class="btn btn-secondary btn-sm">
Rediger</button>
Then, you can access the data by querying this.dataset.department:
function toggleManageDepartmentModal(targetElement) {
// `this` is event's target element
const department = targetElement.dataset.department;
// or rather JSON.parse(targetElement.dataset.department)
// or targetElm.getAttribute('data-department')
…
}
There's one caveat – because data-attributes are part of the 'public' markup, you really should not put anything confidential in there (but I guess that this is not the case).
I ended up taking a little different approch which works very well.
#foreach (var department in Model.PaginatedDepartments())
{
<tr>
<td>#department.Name</td>
<td>#department.Description</td>
<td class="min">#department.Created.ToLocalTime().ToString("dd-MM-yyyy")</td>
<td class="min">
<div class="text-nowrap">
<script>
//Store model JSON in localStorage
localStorage.setItem('department' + #department.Id, JSON.stringify(#Json.Serialize(department)))
</script>
<button type="button" class="btn btn-secondary btn-sm" onclick="toggleManageDepartmentModal(#department.Id)">
<span class="fa-solid fa-pen-to-square" aria-hidden="true"></span>
Rediger
</button>
</div>
</td>
</tr>
}
function toggleManageDepartmentModal(id) {
var modelJSON = localStorage.getItem('department' + id);
var model = {
department : JSON.parse(modelJSON),
controller : 'Admin',
action : 'ManageDepartment'
};
$.ajax({
type: "Post",
url: "/Modals/ShowManageDepartmentModal",
data:model,
success: function (data) {
$("#loadModal").html(data);
$('#modal-manage-department').modal('show')
}
})
}

simplehtmldom trigger click on element

I am trying to trigger a click on the following element, and then get the innertext of it.
<a class="btn btn-sm btn-default" href="javascript:;" onClick="score(238953,this)">Show result</a>
After "onClick" has been triggered, it should look like this:
<a class="btn btn-sm btn-default" href="javascript:;" onClick="score(238953,this)">1 : 2</a>
This is the code I've tried:
$winner = $this->data->find('.btn-sm', 0)->onclick->innertext;
I am trying to get the 1 : 2 from "innertext".
It is not working, and I don't know if it even does. But any help is appreciated.
You can try it using textContent() and jQuery on event handler:
<?php
//php code
?>
<script>
$('.btn-sm').on('click', function() {
var txt = $(this).textContent();
})
</script>

Javascript how to identify button clicked

I have a page with many articles. Each article has a delete button. How can I identify the button clicked for the article?
Currently I have this:
<button type="button" id="delete-article" class="btn btn-small btn-danger">Delete</button>
$('#delete-article').on('click', function(e) {
console.log('Test delete article');
});
This logs 'Test delete article' according to the number of articles on the page.
You can attach the event on button and use this object to refer the currently clicked button:
$('button').on('click', function(e) {
console.log(this.id);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="delete-article" class="btn btn-small btn-danger">Delete</button>
<button type="button" id="delete-article-2" class="btn btn-small btn-danger">Delete</button>
You can use your event variable to get the target of the event (that is, the element responsible) and from there get its id, like this:
let btnId = event.target.id;
However, for that to work properly you should assign unique ids to your buttons. If you want to provide other data (or you don't want to use id) you can append custom attributes, like data-value or similar, and use it like this:
let myValue = event.target.getAttribute('data-value');
You need to establish relation between article and corresponding button, one way to implement is by using HTML5 data attribute.
assign data-articleId to article id in button element and when you click the button you can access which button was clicked by using Jquery .data() function.
<button type="button" data-articleId='123' class="btn btn-small btn-danger delete-article">Delete</button>
$('.delete-article').on('click', function(e) {
$(this).data('articleId'); //will return 123;
console.log('Test delete article');
});
If all the buttons have this markup
<button type="button" id="delete-article" class="btn btn-small btn-danger">Delete</button>
Then the DOM sees them as just one button, you should find a way to attach unique ids to your buttons
You can get an object of clicked button then you can get any details from that object like an index or whatever you want.
$('#delete-article').click(function(){
console.log($(this));
console.log($(this).index());
});
You can directly achieve it by using the JavaScript.
document.addEventListener('click',(e)=>{
console.log(e.target.id)
})
<button type="button" id="delete-article1" class="btn btn-small btn-danger">Delete1</button>
<button type="button" id="delete-article2" class="btn btn-small btn-danger">Delete2</button>
<button type="button" id="delete-article3" class="btn btn-small btn-danger">Delete3</button>
<button type="button" id="delete-article4" class="btn btn-small btn-danger">Delete4</button>
<button type="button" id="delete-article5" class="btn btn-small btn-danger">Delete5</button>
<button type="button" id="delete-article6" class="btn btn-small btn-danger">Delete6</button>
<button type="button" id="delete-article7" class="btn btn-small btn-danger">Delete7</button>

jQuery replace HTML in string

I want to replace following HTML string:
</p><span onclick="alert(event)" class="btn btn-sm btn-success" contenteditable="false">XXX</span><p><br></p>
with:
</p><button onclick="alert(event)" class="btn btn-sm btn-success" contenteditable="false">YYY</button><p><br></p>
using jQuery. I have tried .replace() function, but its not working for some strange reason.
try give span an ID and
You can do:
$("#yourid").text("YYY");
or
$("#yourID").html("testing <b>YYY</b>");
Here you go with a solution https://jsfiddle.net/bqfv5fge/1/
var span = $('span:contains("XXX")');
span.after('<button>YYY</button>');
$(span[0].attributes).each(function() {
$('button:contains("YYY")').prop(this.nodeName, this.nodeValue);
});
span.remove();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span onclick="alert(event)" class="btn btn-sm btn-success" contenteditable="false">XXX</span><p>
test paragraph
</p>
Use jQuery contains to get the target element.
Reference Document: https://api.jquery.com/contains-selector/
First get the reference of span element, then add button next to span using jQuery after.
Then attach all the attribute to the button and then remove span.
Try this, but better to add an ID for selector.
$(document).ready(function(){
$('span').click(function(){
$(this).text('YYY') or $(this).html('YYY');
})
})
var attr ='';
$("span").each(function(){
$.each(this.attributes,function(){
attr += this.name+'="'+this.value+'"';
});
});
$("span").replaceWith('<button '+attr+'>'+$('span').text()+'</button>');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span onclick="alert(event)" class="btn btn-sm btn-success xyz" contenteditable="false">XXX</span>
https://jsfiddle.net/s0bv09gm/.
If you just want to replace "span" with "button" tag:
$(document).ready(function(){
var x = '</p><span onclick="alert(event)" class="btn btn-sm btn-success" contenteditable="false">XXX</span><p><br></p>';
alert(x.replace(/span/g,"button"));
});
https://jsfiddle.net/L26fvfvL/
If you want to replace XXX with YYY:
HTML Code:
<span onclick="alert(event)" class="btn btn-sm btn-success" contenteditable="false">XXX</span>
JQuery Code:
$(document).ready(function(){
var x = $("span");
x.html(x.html().replace("XXX","YYY"));
})
https://jsfiddle.net/f7qsa6kw/
If you want to do both the things, apply the second step and then first step.

Find any sibling that has matching class

I have a toolbar with buttons. Only one button has the class 'btn-info' for instance to indicate it is currently selected.
But it may not be 'btn-info', it could be btn-anything.
If I click any of the buttons in the tool bar I want to know what the matching class is on which ever button is selected.
I have tried:
$('.btn-toggle-group .btn').click(function(){
var selectedClass = $(this).siblings('button[class^="btn-"]').prop('class')
$('.btn-toggle-group .btn').removeClass('btn-info btn-primary btn-danger btn-success btn-warning btn-default')
})
And...
$('.btn-toggle-group .btn').click(function(){
var selectedClass = $(this).parent().find('[class^="btn-"]').prop('class')
$('.btn-toggle-group .btn').removeClass('btn-info btn-primary btn-danger btn-success btn-warning btn-default')
})
But to no avail.
How can I achieve this? The solution in Jquery or pure Javascript is fine (Javascript is preferred as it is native and faster).
<div class="btn-group btn-toggle-group">
<button type="button" class="btn btn-info">Current</button>
<button type="button" class="btn">Deleted</button>
</div>
Try using * instead of ^
$(this).siblings('button[class*="btn-"]').prop('class');
I think you just need to switch to .attr('class') instead of .prop('class'). DOM elements have properties className and classList; you could also use those if preferred.

Categories

Resources