How do I change the id set through an onclick function? - javascript

I have a delete modal set up, and the id of the module I want to be deleted is passed and set to the 'delete' button on the modal. The code below does this for me:
$(document).on("click", "#deleteModule", function () {
var id = $(this).data('id');
$("#deleteModuleButton").attr('data-id', id);
});
What this does is lets me click an 'X' by the module, and after I click that a modal drops down asking me if I'm sure. By clicking the X I pass the id to the modal, so that upon clicking 'I'm sure' it deletes the correct module by id.
Unfortunately it seems that the same id is passed every time I click the function. If I have ids 74, 75, and 76 on a page, I can delete the first one I click, say '74' - then every time I click 'X' on the other modules (75, 76), the initial value that was set from the first deletion (74) is never overwritten by the next element, so the other modules can't be deleted unless I refresh the page and try it again.
Is there something inherent on the onclick function that I'm overlooking, and is there a way to correct this?

If I am understanding your problem correctly, you can try to do something like:
$(document).on("click", "#deleteModule", function () {
var id = this.data('id');
showConfirmClosePrompt(id); // Re-factor to use across all modals
});
That way, you'll have the id no matter what modal id you click the X on. You may want to check to see if var id = $(this).data('id'); is your real problem too.

The answer to this was in the statement:
var id = $(this).data('id');
The better was to do this is:
var id = $(this).attr('data-id', id);
The former binds the same value, whereas the latter does not and can be reused. Changing this line in every repeated instance solved all of my problems!

Related

How to set a value in a bootstrap modal and then pass it in a disabled textbox?

I would like to set a value via a form in a modal and have that value reflected on a disabled textbox in the main screen. What are the best options out there?
It can make work using jQuery with the help of event handler
Handle click event of modal dialog, pass data by selecting #Id into modal and show it
Something like.,
$(document).on("click", ".open-modalDialog", function () {
var mytxtInput1Id = $(this).data('txtInput1');
$(".modal-body #txtInput1").val( mytxtInput1Id );
//you have call modal to open here
$('#addModalDialog').modal('show');
});
Assuming this is bootstrap5:
It seems like you should only get the value after the modal closes... which is what the function attached to myModalEl.addEventListener does.
event.target typical returns the element that has the event listener attached to it, but like I said in the comments in the code below, if it doesn't, then there are a million and one different ways to do so.
var myModalEl = document.getElementById('myModal');
myModalEl.addEventListener('hide.bs.modal', function (event) {
// getElementsByName returns a list of elements, so be sure to select an element to perform on
document.getElementsByName("name_of_hidden_element")[0].value = event.target.getElementsByName("name_of_element_inside_of_modal")[0].value
//event.target.... should work to get the element from inside the modal, but if it doesn't there are several other ways to do so.
});

How to use MDC-Web methods (e.g. MDCIconButtonToggle)

I'm having trouble getting the MDC-Web methods/ framework methods to work. Specifically I'm trying to get the MDCIconButtonToggle to work. I have an icon button that can change when clicked. I thought the way I set it up was correct, but it won't toggle when clicked.
import {MDCIconButtonToggle} from '#material/icon-button';
import {MDCIconButtonToggleFoundation} from '#material/icon-button';
const iconButtonRipple = new MDCRipple(document.querySelector('.mdc-icon-button'));
iconButtonRipple.unbounded = true;
function handleToggleButtonClick(){
console.log("clicked");
const toggleBtn = new MDCIconButtonToggleFoundation(expBtn);
toggleBtn.handleClick();
}
var expBtn = document.getElementById("config-audio-button");
expBtn.addEventListener("click", handleToggleButtonClick);
When I run this, every time I click the button "clicked" is displayed in the console, as expected, but the icon doesn't change/ toggle. If I change MDCIconButtonToggleFoundation to MDCIconButtonToggle, I get an error message in console, but the button toggles.
The error message claims that either expBtn.addEventListener is not a function, or that handleClick is undefined.
I've looked through the main docs, and this, but haven't been able to figure out what I'm doing wrong.
Well done on finding a work-around this.
But for someone else that might be stuck with the same problem, here's the clear cut on how you can properly listen to events directly on a component,a button as an example:
Assume we have a button below:
const someButton = new MDCIconButtonToggle(document.querySelector('.someButton'));
We want to alert("yes") when it's clicked. We would the register the event as follows:
someButton.listen('click', ()=> { alert("yes"); });
Note:
The event name is a normal javascript event like "abort", "scroll", "change" etc.
So after even more searching around I found a listen() method in the MDC Dialog documentation. Just ctrl+f for listen and you will find a few examples.
For whatever reason this is the first and only place I've found a listen() method mentioned. If anyone knows where listen() is explicitly documented, I'd be happy to have a link to it to learn more about it.
Below is my solution. I first get an HTML collection of all the toggle-able elements. Then I iterate over them, and add the listen() event listener method to listen for a change event. Once the change event occurs, the buttons will execute handleClick()/ toggle on/off.
// Get "array" of toggle-able arrow dropdowns.
var expandableArrowButtons = document.getElementsByClassName("mdc-icon-button add-margin-bottom");
// Iterate over all 3 expandable arrow icon buttons, and listen for a change event.
[].forEach.call(expandableArrowButtons, function(element){
const toggleBtn = new MDCIconButtonToggle(element);
toggleBtn.listen('MDCIconButtonToggle:change', function(){
console.log("clicked");
const tb = new MDCIconButtonToggleFoundation(toggleBtn);
tb.handleClick();
});
});

Passing "this" to a function in jQuery problems

sorry but couldn't find a solution for my problem so far.
I am writing a kind of an email template editor as a little task for my boss.
$('a, span').click(function(event){
var editableElement = $(this);
if($(this).is('a')){
event.preventDefault();
}
if(editableElement.is('span')){
processType(editableElement, 'simpleText', modalContent)
When I send the 'editableElement' variable first time, everything's fine, sends object to my function, where I open up a modal window, where there is a textarea, which if i enter text and submit it using only jQuery it will put the text from the textarea (using .val()) to my desired element, in this case a "span" element which is the 'editableElement' using .text() on it. No problem, it works for the first time. After I try to edit a second span, it constantly modifies the previous span too, with whatever I enter in to the textarea (which is cleared out completely, the problem is NOT here) I've ran a fast debug with a simple foreach on the editable element, and the problem is that for some reason it keeps adding objects to the editableElement variable everytime I send it to the function. The number of spans I try to edit, the number of objects will be in my variable all with the index of 0.
Any idea what could be the cause of this?
Thanks in advance!
EDIT:
As requested the whole code in one piece which I have problem with, though it was the whole code before too, I'm in an early stage of writing it, I understand that it was hard to read though, perhaps now it is properly formatted as requested.
$(window).load(function()
{
var modalContent = $('#modalContent');
modalOverlay = $('#modalOverlay');
$('a, span').click(function(event)
{
var editableElement = $(this);
if($(this).is('a'))
{
event.preventDefault();
}
if(editableElement.is('span'))
{
processType(editableElement, 'simpleText', modalContent)
}
});
$('#codeGenButton').click(function()
{
var container = $('#codeContainer');
container.empty();
container.text(getPageHTML());
});
$('#modalClose').click(function()
{
$(this).parent().parent().animate({'opacity': '0'}, 200,
function(){
$(this).css({'display': 'none'});
});
});
});
function fillData(targetDomElement, modalObject)
{
$('#modalSubmit').click(function(){
targetDomElement.text($('#simpleTextEdit').val());
closeModalWindow();
});
}
function processType(targetDomElement, type, modalObject)
{
modalObject.empty();
if(type == 'simpleText')
{
modalObject.append("<p id='simpleTextEditTitle'>Text editor</p><textarea id='simpleTextEdit'></textarea>");
getModalWindow();
fillData(targetDomElement, modalObject);
}
}
Step by step of what it should do:
First of all, the html should not be needed for this, it does not matter, and this is the whole code honestly.
When you click on either an element of (span) or an element of (a) it triggers the function.
It will check if it was actually a (span), or an (a) element.
Currently if it is an element (a), it does nothing, not implemented yet, but if it is a (span), it will call in the processType function, which it sends the "handler?" of the element to namely "editableElement" which has been declared right after the click event, the 'simpleText' which gets send too, is just to differentiate between element types I will send to the processType function later on, and for the last, "modalConotent" is only a div container, nothing more.
Once the function gets the data first, it will make sure, that the modal window gets cleared of ALL data that is inside of it, then it will append a bit of html code as you can see, in to the modal window, which pops up right after I have appended data in to it, it is literally just a 'display: block' and 'animate: opacity: 1' nothing special there.
Lastly it will trigger the 'fillData' function, which will put my desired data from '#simpleTextField' which is only a (textarea) where you can write in, to my desired element 'editableElement' which is the element you have clicked at the first place, a (span) element after the submit, which is again, just a css of 'display: none' and 'opacity: 0' closes the modal window.
THE END.
Your problem is here
function fillData(targetDomElement, modalObject)
{
$('#modalSubmit').click(function(){
targetDomElement.text($('#simpleTextEdit').val());
closeModalWindow();
});
}
Each time this function is called it adds a new click handler with the perameters at the time the handler was created. This handler is added in addition to the already created handlers. See a demo here. After successive clicks on the spans notices how fillData is called multiple times for a single click.
To give you the best possible answer I need to know where your modalSubmit button is in relation to modalContent. Also is is modalSubmit dynamic or static on the page?
Here is a fairly hacky fix in the mean time using on and off to bind and remove the handler respectively:
function fillData(targetDomElement, modalObject)
{
$('#modalSubmit').off("click"); /*Clear Hanlders*/
$('#modalSubmit').on("click", function(){
console.log("fill data");
console.log(targetDomElement);
targetDomElement.text($('#simpleTextEdit').val());
/*closeModalWindow(); Don't have anything for this so ignoring it*/
});
}
Demo
I've solved it myself by using .submit() (of course this means adding form, and an input with the type of submit) instead of .click() when I send the request to modify the element I've clicked on originally.
I don't understand though, why it did what it did when I've used the .click() trigger.

function handle jQuery event and parameter?

Take the following code,
// Update button clicked
function updateEntity(e) {
e.preventDefault();
var name = $(this).attr("name");
...
// some stuff
...
}
$(document).on("click", ".updateEntity", updateEntity);
Currently I have this for (go figure) updating an entity I've editted on button click. Now, its parameter is particularly expecting a jQuery event. However, I want to also be able to call this function (end goal: to minimize code) outside of a jQuery event. Like so,
// Do an update but then redirect to prevent adding the same estimate twice.
function createEstimate(e) {
updateEntity(e);
var link = $(this).attr("href");
window.location.href = link;
}
$(document).on("click", ".createEntity", createEstimate);
Question: How would I go about calling updateEntity or setting the function up, so that I can supply it to the click-event handler and call it like a function and still have it used correctly? Is this goal realistic or should I be structuring this differently if I want to achieve such a goal?
(Encase it is not obvious, my current problem is that on the function call updateEntity(e); $(this) becomes window instead of the clicked link.)
Use .call to set this correctly:
updateEntity.call(this, e);
Learn more about this.

Problem passing integer variable into click event in javascript and jquery

This is probably something simple but it's driving me nuts.
I'm making some pagination using jquery and a while loop which has a variable called "pageNum" that updates at the end of the loop and represents the page being written out. Obviously pageNum is added to at the end of each iteration. Fine.
Here's the code that's giving me a hard time:
$('#page' + pageNum).click(function(){
alert(pageNum);
});
So that id works properly and will assign a click even to (for example) a span with an id of page3 if 3 is the current pageNum. The problem is, when I click on that span, the pageNum that is alerted is always the last value of pageNum that was set in the loop. So if there's 8 pages, it will always alert 8. So, I figured it must be always pulling in the current value, so I tried passing pageNum in like this:
$('#page' + pageNum).click(function(pageNum){
alert(pageNum);
});
But now the alert shows [Object object].
I've tried creating variables inside and out of the click event and assigning them the value of pageNum and nothing seems to work.
This must be something really stupid, can someone please help me out? I need to have the current pageNum usable within that click event.
Thanks in advance for your help!.
Instead of referencing the pageNum variable directly, just get it dynamically from each link, for example:
$('#page' + pageNum).click(function(){
alert(this.id.replace('page',''));
});
Or give them a class, say .pageLink and bind them all at once, like this:
$('.pageLink').click(function(){
alert(this.id.replace('page',''));
});
Currently you're referencing a single pageNum variable from your loop which changes and ends up whatever it was at the end of the loop. You either need to pass it in a closure or ignore it altogether, like above, or use event data passed to .bind(), like this:
$('#page' + pageNum).bind({id: pageNum}, 'click', function(e) {
alert(e.data.id);
});
The third option actually works great, Nick just had the parameters mixed around - I recently needed to use bind in this fashion for a plugin im creating and it works awesome! See below for fix:
$('#page' + pageNum).bind('click', {id: pageNum}, function(e) {
alert(e.data.id);
});
jQuery documentation cleared it up for me; http://api.jquery.com/bind/
.bind( eventType, [ eventData ], handler(eventObject) )
$('#page' + pageNum).click(function()
{
var pageNum = $( this ).attr( 'id' ).match(/page([0-9]*)/)[1];
alert( pageNum );
});

Categories