I'm new to JQuery and I'm messing it up...
I'm trying to build a tour for my website. I have this function for building and showing the popovers.
They do show up, but the buttons just work in the first popover (with only one button).
This is the code I have right now:
function createButton(i){ //Creates buttons for later appending to popover's content
if (i==0){ //First popover, just needs "Next" button
return '<a class="btn btn-light border border-dark float-right mb-2" >Next</a>';
}
else if(i<popovers.length-1){ //Popovers in the middle need both "Previous" and "Next" buttons
var buttons = new Array();
buttons[0] = '<a class="btn btn-light border border-dark float-left mb-2">Previous</a>';
buttons[1] = '<a class="btn btn-light border border-dark float-right mb-2">Next</a>';
return buttons;
}
else{ //The last popover only needs a "Finish" button
return '<a class="btn btn-light border border-dark float-right mb-2">Finish</a>';
}
}
The problem must be here:
function showPopover(i){
var current = popovers[i];
var button = $(createButton(i));
current.popover('toggle');
var new_position = $('.popover').offset();
var content = $('.popover-body');
if(button.length == 2){
$(button[0]).appendTo(content);
$(button[1]).appendTo(content);
}
else{
button.appendTo(content);
}
window.scrollTo( new_position.left, new_position.top - 60 );
if(button.length == 2){
$(button[0]).click(function ()
{
current.popover('toggle');
content.detach();
i--;
if(i>=0){
showPopover(i);
}
});
$(button[1]).click(function ()
{
current.popover('toggle');
content.detach();
i++;
if(i!=popovers.length){
showPopover(i);
}
});
}
else{
button.click(function ()
{
current.popover( 'toggle' );
content.detach();
i++;
if(i!=popovers.length){
showPopover(i);
}
});
}
};
While inspecting the buttons, I could see that there's no event attached to them, so the problem is in the click functions.I thought I might be using wrongly the JQuery selectors; however, the append functions do work and show the buttons on the popover.
Thanks for your answers!
I think first you append those buttons to the DOM and then only attach the events.
since I can see you are using $(button[0]) something. jQuery will search that element in DOM and attache the click event there. and on more thing button[0] is not an actual DOM object yet at that point it is just a string.
Related
I'm using bootstrap 3 and dynamically creating buttons with a elements of the type
<a class="btn btn-primary" data-id="1" data-toggle="modal" data-target=".ver-persona">
<i class="fas fa-search"></i> Ver
</a>
My script to generate the button is:
let boton_elem = $('<a>');
boton_elem.addClass('btn');
for(let clase_btn in botones[boton].clases){
boton_elem.addClass(botones[boton].clases[clase_btn]);
}
for(let data_btn in botones[boton].datas){
boton_elem.data(botones[boton].datas[data_btn][0],botones[boton].datas[data_btn][1]);
}
if(botones[boton].icon !== undefined){
let icon_elem = $('<i>');
for(let clase_icon in botones[boton].icon.clases){
icon_elem.addClass(botones[boton].icon.clases[clase_icon]);
}
icon_elem.appendTo(boton_elem);
}
if(botones[boton].valor.length > 0){
boton_elem.html(boton_elem.html() + ' '+ botones[boton].valor);
}
if(botones[boton].listens !== undefined){
for(let listen in botones[boton].listens){
$('#'+tabla).on(botones[boton].listens[listen].evento,botones[boton].listens[listen].botones[boton].listens[listen].funcion);
}
}
boton_elem.appendTo(columna_elem);
The buttons are created perfect, the data is in it, and all parameters are applied correctly, but the .ver-persona modal not open with the generated button, all of buttons loaded with the page works perfectly and the modal opens normally.
Exist any way to refresh or reassing bootstrap listeners when a button is created? or some function to get button advised to open the modal?
I make this fiddle for reference: Live example
Thanks in advance.
For dynamic content, you can add data attributes using .attr of jQuery. So instead of boton_elem.data(boton.datas[data_btn][0],boton.datas[data_btn][1]); you can re-write it as boton_elem.attr("data-"+boton.datas[data_btn][0],boton.datas[data_btn][1]);
You can test it here
I have a bootstrap button with a font-awesome icon on it.
<button type="button" class="btn pull-right rotate-picture-right" aria-label="Rotate" id="picture{{ picture.pk }}">
<i class="fa fa-repeat" id="testright" aria-hidden="true"></i>
</button>
My on-click event:
$(document).on('click', '.rotate-picture-right', function (e) {
rotate_and_reload(e, "right");
});
The function:
function rotate_and_reload(e, direction){
var picture_id = e.target.id.replace("picture", "")
var url = "{% url "device-api-picture-rotate" device.pk 0 "placeholder" %}".replace("pictures/0", "pictures/"+picture_id).replace("placeholder", direction)
$.ajax({
url: url,
type: 'PATCH',
success: function() {
var d = new Date();
img = e.target.parentElement.parentElement.getElementsByTagName('img')[0];
if (img.src.includes("?")){
img.src = img.src.split("?")[0] + '?' + d.getTime();
} else {
img.src = img.src + '?' + d.getTime();
}
},
});
}
In Firefox, it doesn't make any difference whether I click on the icon or on the button, the on click event is triggered for the button.
In Chrome however, it is also possible to click on the icon and as I am using several properties of the buttons data, my function fails if I only get the icons information.
Is there a way to "disable" the icon and only make it be there and be pretty but not be able to trigger anything?
You can use CSS to disable pointer events on the icon.
<button type="button" class="btn pull-right rotate-picture-right" aria-label="Rotate" id="picture{{ picture.pk }}">
<i class="fa fa-repeat" style="pointer-events:none" id="testright" aria-hidden="true"></i>
</button>
However, a better way to handle this would be to ensure that the event.target is the same as the event.currentTarget in your click event handler. You can always get the reference of the button and not the icon by looking at the event.currentTarget property. The property name might be different based on whether you are using vanilla JS or a framework like jQuery.
Sample:
$('button').click(function(e) {
console.log(e.currentTarget); // This will be the button even if you click the icon
})
Handy reference for different Event Targets
enter image description hereI specified the button class in CSS selector and right click executed.
Then options displayed on the button, so it assure that the correct element position has been acquired.
javascript
.then(function () {
var element = driver.findElement(By.className('xxx'))
return element;
})
.then(function (element) {
var action = new webdriver.ActionSequence(driver)
action.click(element, webdriver.Button.RIGHT).perform()
})
Problem arises when just click is executed, instead of right click.
.then(function (element) {
var action = new webdriver.ActionSequence(driver)
action.click(element).perform()
})
I hope the event when the button is pressed to be executed, but it doesn't. I cannot find any error message. I really don't know why...
html
<button class="btn btn-default btn-play">
<span class="glyphicon glyphicon-play" aria-hidden="true">
</span>
" play "
</button>
I tried to select each class and result was same.
button before
button after
Since the aria-hidden="true" you can achieve this by directly clicking using javascript. :)
driver.executeScript("document.getElementsByClassName('btn btn-default btn-play')[0].click()")
Actually I was struggling in making 'like' buttons which on clicking increases or decreases the count whenever clicked and the problem I am facing is ,the interference of one button on other buttons.Here is my html code for one button:
<button class="btn btn-default buttonattr"style="font-family:Pangolin" onclick="myhit1(\''+this["post"]+'\',\''+this["id"]+'\',\''+this["love"]+'\');myclick()">
<span class="glyphicon glyphicon-heart fa-lg active1"></span> Love
</button>;
where myhit() and myclick()are javascript functions, called on clicking this button . Here is my javascript functions:
var toAdd=1;var newValue=0;
var overall=1;var pvalue=0;
function myhit(post,id,love){
oldValue=parseInt(love);
if(toAdd>0){
newValue=oldValue+toAdd;
}
else{
newValue= overall + toAdd;
}
pvalue=pvalue+toAdd;
toAdd*=-1;
overall=newValue;
$.post('porthome4_.php',{post1:post,id1:id,love:newValue,plove:pvalue},function(info){});
}
I have made more 'like' buttons for each post. The problem is for eg. if I click on one button and the counter is increased from 0->1 state ,but if click on another button its state change is absurd , and I know is the reason is toAdd variable state change from +1 to -1 because its state change for every click on button ,,it would have worked fine if there would have been only 1 button but
for multiple buttons this wont work...Can someone suggest me better way to tackle this or a change in my function code would be much more appreciated . Would be glad if someone helps.Thank u
<button class="btn btn-default buttonattr"style="font-family:Pangolin" data-state="1" onclick="myhit1(\''+this["post"]+'\',\''+this["id"]+'\',\''+this["love"]+'\');myclick()">
<span class="glyphicon glyphicon-heart fa-lg active1"></span> Love
</button>
var newValue=0;
var overall=1;
var pvalue=0;
function myhit(post,id,love)
{
oldValue = parseInt(love);
var toAdd = parseInt($(this).attr("data-state"));
if(toAdd>0)
{
newValue=oldValue+toAdd;
}
else
{
newValue= overall + toAdd;
}
pvalue=pvalue+toAdd;
toAdd*=-1;
overall=newValue;
$(this).attr("data-state",toAdd);
$.post('porthome4_.php',{post1:post,id1:id,love:newValue,plove:pvalue},function(info){});
}
You can used separate state variable for each button. Set data-state attribute to button and after that you can used this attribute to function $(this).data("data-state"); you can get and set this value each time whne button click.
I have a complex Javascript app which populates a button depending on the app state and readonly permissions:
But essentially the button looks like this when it is added to the document:
<button type="button" id="..." class="btn btn-link btn-table-action btn-table-add-row" title="Add"></button>
The id is auto generated and is not known before hand. Besides we have several of these buttons, that all need to be disabled/enabled simultaneously.
I tried the following with no luck:
$(".btn-table-add-row").prop('disabled', true);
setInterval(function() {
$(".btn-table-add-row").prop('disabled', true);
}, 1000);
var elems = document.getElementsByClassName("btn-table-add-row");
console.log(elems);
for(var i = 0; i < elems.length; i++) {
elems[i].disabled = true;
}
The above examples were all tried on page load, after the document has loaded and the buttons are visible. I am able to read the elems list in the last example, but they will not disable. Any suggestions?
I created a fiddle http://jsfiddle.net/mfleshman/yR9U3/
<button type="button" class="btn btn-link btn-table-action btn-table-add-row" title="Add">test</button>
<button type="button" class="btn btn-link btn-table-action btn-table-add-hide" title="Add">test</button>
$(".btn-table-add-row").prop('disabled', true);
$(".btn-table-add-hide").hide();
You stated the buttons are "visible". Disabling a button will not hide it from the page unless you have additional CSS selectors doing this.
If you are trying to hide the buttons you need to call .hide() on the element.
As Satpal and yourself have mentioned, the code is correct (at least the first sentence i tried), so the problem will be either in the order in which the buttons are created, or maybe in an error during the execution of other JS code that causes yours to not run.
I also created a fiddle for this and your code is working: http://jsfiddle.net/gx7zC/
$(document).ready(function(){
var btnAmount = Math.floor((Math.random() * 10) + 1);
for(var i=0; i<btnAmount;i++){
var newButton = document.createElement("button");
$(newButton).addClass("btn btn-link btn-table-action btn-table-add-row");
newButton.id = "btn"+i;
$(newButton).text("btn"+i);
document.body.appendChild(newButton);
}
$(".btn-table-add-row").prop('disabled', true);
});