Accessing dynamically created variable in onclick - javascript

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')
}
})
}

Related

Bootstrap 4 Modal PHP Dynamic Variable Access

I have a PDO object with a certain number of DB entries. I'm looping through every result generating HTML content. Furhtermore, if a user is logged in, I am displaying extra buttons to edit and delete the content, like so:
if (isset($_SESSION['login']) and $_SESSION['idMembre'] == $id_utilisateur) { ?>
<br>
<a class="btn btn-outline-secondary btn-sm" href="" id="modify" data-toggle="modal" data-target="#modifierRecette" data-id="<?=$recette->idRecette;?>" onclick="modifierRecette(<?= $recette->idRecette; ?>)">Modifier</a>
<span>|</span>
<a class="btn btn-outline-danger btn-sm" href="" value="submit" onclick="supprimerRecette(<?=$recette->idRecette;?>)">Supprimer</a>
<?php } ?>
When the user clicks on "Modifier", a modal pops-up. Idea is that user can change some data inside the modal and click on a "Save Changes" button to commit the changes to the DB.
However, I have a hard time accessing to my PDO loop-through from within the modal.
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" onclick="sauvegarderRecette(<?= $recette->idRecette; ?>)">Sauvegarder</button>
</div>
Idea being in every loop-through, the function "sauvegarderRecette()" would get the unique ID of the data object I am working with. This in turn fires off an AJAX script to send the data to the DB:
function sauvegarderRecette(idRecette) {
let request = $.ajax({
'url' : 'ajax/sauvegarderRecette.php',
'type' : 'POST',
'data' : {
'idRecette' : idRecette
}
});
The issue now is that every loop-through, the ajax function sends off the same idRecette to the PHP script.
Any ideas on how I can dynamically access variable from JavaScript so it 'preserves' the value from the loop-through?
I thank you in advance for your help.

Issue with data-th-id

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');

How to change html inside a span

I want to change the content of a span in my form
HTML:
<form action="javascript:submit()" id="form" class="panel_frame">
<label>Origin:</label>
<div class="input-group" id="input-group">
<input type="text" id="origin" name="origin" class="form-control">
<span class="input-group-btn">
<button id="btn-default" class="btn btn-default" type="button">
<span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span>
</button>
</span>
</div>
What I want change is che content of <span class="input-group-btn"> with
<button id="btn-default" class="btn btn-default" type="button">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
So what change is: the icon pushpin to remove and the action useCurrentPosition to clearPosition.
I' using jquery and despite I've read other answer about similar question on Stack like: How can I change the text inside my <span> with jQuery? and how to set a value for a span using JQuery I haven't solved the issue.
I tried:
$("#input-group span").html('
<button id="btn-default" class="btn btn-default" type="button" onclick="br_bus.useCurrentPosition()">
<span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span>
</button>
');
,giving an id to the span and also modify the full div, but none solved my problem.
What am I missing?
Here's a way to overcome the problem of changing the onclick attribute, which is bad practice, without storing a Global var, and using jQuery delegation (learn to use it, it's really good):
$(document).on('click','.btn', positionChange); // Give that button an id on his own and replace '.btn' with '#newId'
// Not using an anonymous function makes it easire to Debug
function positionChange(){
var $btn = $(this), // Caching jQuery elements is good practice
$span = $btn.find('span'), // Just caching
pushpinApplied = $span.hasClass('glyphicon-pushpin'); // Check which icon is applied
( pushpinApplied ) ? useCurrentPosition() : clearPosition();
$span.toggleClass( 'glyphicon-pushpin glyphicon-remove' );
}
Rather than changing the function called in the onclick attribute I suggest having a flag in one function to define the logic it should follow.
For example:
function positionChange(this){
var $this = $(this);
if(!$this.data("currentpositionused")){
//useCurrentPosition() code here
$this.data("currentpositionused", true);
}
else {
//clearPosition() code here
$this.data("currentpositionused", false);
}
Then change your HTML to:
<button class="btn btn-default" type="button" onclick="positionChange(this)">
If you want to change only the onclick attribute of the button inside the particular span you can use the following in your script.,
$(document).ready(function(){
$("span.input-group-btn button").attr("onclick","clearPosition()");
});
EDIT
$(document).ready(function(){
$("span.input-group-btn button").attr("onclick","clearPosition()");
$("span.input-group-btn button span").attr("class","Your_class");
});
And also learn about how to change/add/remove attribute values....
Try this:
$("span.input-group-btn").html('<button class="btn btn-default" type="button" onclick="clearPosition()">
<span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span>
</button>');
Is it like This ?
how to change onclick event with jquery?
$("#id").attr("onclick","new_function_name()");
jquery change class name
$("#td_id").attr('class', 'newClass');
If you want to add a class, use .addclass() instead, like this:
$("#td_id").addClass('newClass');

Swap 2 div elements Javascript

So I want to swap two div elements that have a CKEditor inside. I viewed some of the previous questions and tried to do it that way. It's all OK, the elements are swapped. But one of the elements loses its content and becomes non-editable.
<div id="sections">
<div id="apresentacao_div">
<label id="apresentacao_label" for="apresentacao">Apresentação</label>
<button class="btn btn-default">
<span class="glyphicon glyphicon-remove"></span>
</button>
<button class="btn btn-default">
<span class="glyphicon glyphicon-arrow-up"></span>
</button>
<CKEditor:CKEditorControl ID="apresentacao"></CKEditor:CKEditorControl>
</div>
<div id="intro_div">
<label id="intro_label" for="intro">Introdução</label>
<button class="btn btn-default" onclick="remove(this)">
<span class="glyphicon glyphicon-remove"></span>
</button>
<button class="btn btn-default" onclick="upDiv(this)">
<span class="glyphicon glyphicon-arrow-up"></span>
</button>
<CKEditor:CKEditorControl ID="intro"></CKEditor:CKEditorControl>
</div>
</div>
I want to swap the two divs within the div with the id = "sections". And this is my code to swap:
function upDiv(ex) {
var div = document.getElementById("sections").getElementsByTagName("div");
for (i = 0; i < div.length; i = i + 4) {
if (div[i + 4].id.localeCompare(ex.parentNode.id) == 0) {
swapElements(div[i + 4], div[i]);
return false;
}
}
return false;
}
function swapElements(obj1, obj2) {
obj2.nextSibling === obj1 ? obj1.parentNode.insertBefore(obj2, obj1.nextSibling) : obj1.parentNode.insertBefore(obj2, obj1);
}
The for loop increments by 4 because of the transformation of the textarea into CKEditor adds a lot of new divs (4 in this case).
Can anyone help?
Not having too much familiarity with exactly what you are doing but i would try using a 'clone' method and then removing the original element off the page. It may be the values are not being copied, only the outline is but a clone should mean it duplicates as it is on the page and not how it is from the page source.
What about just swapping the data instead? Moving the DOM elements around is causing problems to me as well, but this works:
Replace your upDiv with this:
function upDiv()
{
var introData = CKEDITOR.instances['intro'].getData();
var presentacaoData = CKEDITOR.instances['apresentacao'].getData();
CKEDITOR.instances['intro'].setData(presentacaoData);
CKEDITOR.instances['apresentacao'].setData(introData);
return false;
}
This takes the data from one, and puts it in the other and vice versa.
Also, I noticed your controls don't have the runat server attribute set. You may want to change this:
<CKEditor:CKEditorControl runat="server" ID="intro"></CKEditor:CKEditorControl>
Finally, you call the function from your button like this:
<button class="btn btn-default" onclick="return upDiv();">
<span class="glyphicon glyphicon-arrow-up"></span>
</button>

Codeigniter route on button click

Hi I am using codeigniter for this project
I have a button element as below
<div class=" pull-right" id="container">
<button class="btn btn-info">
<a style="text-decoration:none;color:white" href="">Guide</a>
</button>
</div>
This button element is part of a div which is one of the results from the search. When I click on the button, how do i pass the information of the div to the controller I want? The information I want to pass is just the element id of the div which is "container".
Try do like that
<button class="btn btn-info">
<a style="text-decoration:none;color:white" href="control/method/value">Guide</a>
</button>
In your class can do like that
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Control extends CI_Controller {
public function method($value) {
// Your value is in $value;
}
}
[Update]
Getting the parent ID element dynamically
<div class=" pull-right" id="container">
<button class="btn btn-info" onclick="window.location='/controller/method/' + this.parentNode.id;">
<a style="text-decoration:none;color:white">Guide</a>
</button>
</div>
Using jQuery:
$('.btn').click(function () {
$.ajax({
type : "POST",
url : 'controller/method',
data: {id : $(this).parent().attr('id')},
success : function(data) {}
});
});
In your controller:
$id = $this->input->post('id', TRUE);

Categories

Resources