I have a modal with a grid of buttons representing different html components. When one of the buttons is pressed, some html is supposed to be injected into the page once the modal closes. However, I'm having trouble targeting the specific column where the html is to be injected. Here's my code:
<div class="row" id="newRow">
<div class="col-md-12 column">
<button class="btn addElement" href="#" data-toggle="modal" data-target="#add-element"><i class="fa fa-plus fa-3x add-item"></i></button>
</div>
</div>
And in my js file I have some code to assign an id to the column div (since there could potentially be many columns with this addElement button) that looks like this:
...
$(this).parent().next().children().find('.column').assignId();
...
Up to this point, everything works well. I'm having no trouble getting the column a unique id (defined in my assignId() function).
As I mentioned, the addElement button gets clicked, opening a modal which is when this code is executed:
$(document).on('click', 'button.addElement', function (e) {
e.preventDefault();
$('#add-element').modal('show').draggable();
var col = $('button.addElement').parent();
// debugging in the browser verifies that the colId
// successfully stores the id attribute for the column
var colId = col.attr('id');
addElements(colId);
});
...
function addElements(colId) {
$('#insert-paragraph').on('click', function () {
var html_content = '<div class="box" data-type="paragraph">...</div>';
$("#newRow").find("#"+colId).html(html_content)
$('#add-element').modal('hide');
});
}
It's on this line: $("#newRow").find(colId).html(html_content); that I'm having the issue. My guess is that the formatting for find(...) is wrong and that I can't just insert a variable like that, but I've tried a few different things and nothing seems to be working.
Any help is very much appreciated.
Thanks!
UPDATE:
#juvian suggested writing a few of the variables' values to the console:
console.log(colId);
console.log($("#newRow")).length;
console.log($("#newRow").find("#"+colId).length);
console.log($("#newRow").find("#"+colId).html());
I logged these values twice. First, just before passing colId into the addElements function and in the addElements function immediately after $(#newRow").find("#"+colId).html(html_content); The results of those two tests are as follows:
Values prior to running addElements:
console.log(colId); = 8153-1076-641d-3840
console.log($("#newRow")).length; = Object[div#newRow.row.clearfix]
console.log($("#newRow").find("#"+colId).length); = 1
console.log($("#newRow").find("#"+colId).html()); = <button class="btn addElement"...>...</button>
Values after the insert-paragraph button is pressed:
console.log(colId); = 8153-1076-641d-3840
console.log($("#newRow")).length; = Object[div#newRow.row.clearfix]
console.log($("#newRow").find("#"+colId).length); = 1
console.log($("#newRow").find("#"+colId).html()); = <div class="box box-element" data-type="paragraph">...</div>
Interestingly enough, it appears like everything is working like I'd expect it to, however, when it's all said and done, the addElement button remains and the page still renders this:
<div id="newRow" class="row clearfix">
<div id="32aa-ab91-f50d-c3b3" class="col-md-12 column ui-sortable">
<button class="btn addElement" data-target="#add-element" data-toggle="modal" href="#">
<i class="fa fa-plus fa-3x add-item"></i>
</button>
</div>
</div>
.find as most jquery functions, takes a css selector as parametre. Unfortunately, colId is just a string, so it matches no elements (unless colId is html, span or something like that)
You are just missing adding the id selector at the beginning to do an id match:
.find("#"+colId)
I guess The parent of button is a div here which has no id.
var col = $('button.addElement').parent();
thus var colId is getting no value.give that div an id and it should be fine.
Related
I want to send a value from html to javascript using javascript variable.
I've created a div from javascript like this:
<body>
<div id="row" class="category-cards">
// creates from js
</div>
</body>
<script>
var d1 = document.getElementById("row");
for (let i=5; i>0; i--) {
d1.insertAdjacentHTML('beforeend',
<div class="card card-small card-category">
<div class="card-del-btn">
<button id="btnDel" onclick="deleteCategory(i)"> <b> × </b> </button>
</div>
<!-- displays the record --!>
</div>
}
function deleteCategory(index){
// takes the index and searches the mysql database for match, and deletes the record
}
</script>
Each iteration of the for loop inserts a card of a record from the database, and I wish to delete that record from the document, as well as the database, when the button is clicked.
Is there a way to associate a unique id or value to each card and send it through the onclick?
I have tried sending the value of i but it is always the last index, which in this case was 0.
There many ways to achieve what you looking for but simplest one would be to use custom html attributes and provide element that triggered event as argument to your callback.
This could be achieved like this
function handleClick(element) {
const elementData = element.getAttribute('data-my-data')
// do some stuff here with element data
}
Using your code:
d1.insertAdjacentHTML('beforeend', `
<div class="card card-small card-category">
<div class="card-del-btn">
<button data-my-data="here goes your data" onclick="handleClick(element)"> <b> × </b> </button>
</div>
</div>
`)
I have a load more button on my page
<a class="btn btn-link border-top px-3 mt-5" role="button" id="reveal">Load more</a></p>
And an onclick function that loads content inside this div:
<div id="ajax-content" class="row m-0">
</div>
The script works and loads more content every time I click the button:
<script>
$('#reveal').on('click', function() {
$('#ajax-content').load('/wp-content/themes/template/ajax-news.php?offset=4');
$('#ajax-content').attr('id', '#ajax-contented');
})
</script>
But I need the offset-variable to increase by 4 every time I click it, so the content that loads is not the same. Hope anyone can point me to the right direction to make this work.
To achieve this you could use a data attribute on the a element which you increment by 4 on each successive click event:
$('#reveal').on('click', function(e) {
e.preventDefault();
let offset = ($(this).data('offset') || 0) + 4;
//$('#ajax-content').load('/wp-content/themes/heidner/ajax-aktuelt.php?offset=' + offset);
$('#ajax-content').html(offset);
$(this).data('offset', offset);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Last flere saker</p>
<div id="ajax-content" class="row m-0"></div>
This would also be possible with a global variable, but they are bad practice and should be avoided where possible.
In addition, note that changing id attributes at runtime is also not good practice. In this case it would stop the repeated clicks from updating the content. As such I removed that line.
I am new to front-end. Now, Here I have 3 divs which will be on the same page.and the position will also be same. it is like toggling .
So at the start this will be the div that I will show
<div text-angular id="htmlEditorId" >Abc</div>
then there is button whick is like
<button class="col-xs-3 btn btn-default" ng-click="changeTab()">NextTab </button>
On click of that button
<div text-angular id="secon">abcd</div>
this div should be shown and not the previous one.
And on again click of that button a third div
<div text-angular id="third">azzzbcd</div>
this should be seen and again on click first one should show . Its like a round robin fashion .
Now what I tried is using ng-show and ng-if. Can any one help me with this?
$scope.changeTab = function() {
$scope.showfirst = true;
$scope.showsecond = false;
}
It's quite simple, you can do it in many ways, for example:
In the controller
Define a scoped variable (bindable with the front-end)
$scope.showView = "firstView"
Define also a function:
$scope.changeView = function(value) {
$scope.showView = value;
}
In the html page define your divs and button
<button ng-click="changeView('secondView')">Chage View</button>
<div ng-show="showView == 'firstView'">abcd</div>
<div ng-show="showView == 'secondView'">abcd</div>
I have this tag:
<td align="center">
<div class="dropdown">
<button onclick="DropdownShow(this)" class="btn btn-default glyphicon glyphicon-picture"></button>
<div id="#TableRowId" class="dropdown-content">
Show
Edit
</div>
</div>
</td>
and JS function:
function DropdownShow(element) {
var elm = document.getElementById(element.querySelector(".dropdown-content").id);
elm.classList.toggle('show');
}
I want when I click on the image glyphicon at the table, to show the dropdown div tag with the class="dropdown-content". To do that I need the each row ID, and I have it on the variable #TableRowId. How can I do that?
You are passing the reference of clicked button so you need to get the element by getting its parent element where parent node can get from parentNode property.
function DropdownShow(element) {
var elm = element.parentNode.querySelector('.dropdown-content')
elm.classList.toggle('show');
}
FYI: If there is no whitespace after the button then you can use nextSibling property to get the element.
var elm = element.nextSibling;
or use nextElementSibling property to get the element even there is a text node.
var elm = element.nextElementSibling;
Check polyfill option for ie8.
I would pass the #TableRowId to the button as a data attribute like this:
<td align="center">
<div class="dropdown">
<button data-dropdown-content-id="#TableRowId" onclick="DropdownShow(this)" class="btn btn-default glyphicon glyphicon-picture"></button>
<div id="#TableRowId" class="dropdown-content">
Show
Edit
</div>
</div>
</td>
And then your javascript would simply be:
function DropdownShow(element) {
var dropDownContentId = element.getAttribute("data-dropdown-content-id");
var elm = document.getElementById(dropdownContentId);
elm.classList.toggle('show');
}
This would give you the most robust code, because it doesn't depend on the relationships (sibling/parent/child etc) between the two elements.
This application have 2 components, a HTML page which contain some element and a JavaScript to generate buttons.
I will try to give out a simplify example in the question for now, but if there's something unclear then i would upload the full code later.
I am using HandleBar.js to generate different contents in the html but don't worry if you don't have any idea about this plugin i will make another non-handlebar.js version.
Consider the Html part looks like below:
HandleBar.js version
//example:
//{{feedId}} = 0t454g465754754h456
//{{url}} = www.jegdo.co.uk
{{each}}
<div class="feedIdChecker">{{feedId}}</div>
<div class="{{feedId}}-EditRegionUrl" >{{url}}</div>
<button class="output-{{feedId}}">Output</button>
{{/each}}
Then i have a JQuery function which would output the url
var feedId = $(".feedIdChecker").html();
$('".output-'+feedId+'"').click(function(){
var postUrl = $('".'+feedId+'-EditRegionUrl"').html();
console.log(postUrl );
});
});
}
I found there's no way to identify which button is which. Since i need to declare the var feedID outside the button, it would always get the first feedID it founds and append to all buttons, how may i solve it? Please tell me if this question is confuse, i will try to explain it in a better way.
There's lots of people trying to help me but it seem i need to give out some more details in order for better understanding:
Javascript:
var initRegionEdit = function(){
var feedId = $(".feedIdChecker").html();
$(".CTHK").click(function(){
var postUrl = ($(this).prev('div').html());
})
}
HTML
<div class="EditRegionUrl" >{{url}}</div>
<div class="feedIdChecker">{{feedId}}</div>
{{#if region}}
<span class="dropdown"><i class="fa fa-map-marker" aria-hidden="true" style="color:gray;"></i>
<span class="result-date result-date-region" type="button" data-toggle="dropdown">{{region}}
<span class="caret"></span></span>
<ul class="dropdown-menu" style="min-width:100px;text-align:center;">
<li class="CTHK" data-url="{{url}}" style=" margin-top: 0px !important;margin-bottom: 0px !important;">Hong Kong</li><div class="divider"></div>
<li class="CTTW" style=" margin-top: 0px !important;margin-bottom: 0px !important;">Taiwan</li><div class="divider"></div>
</ul>
</span>
{{/if}}
I wish above information can help
So when you select $(".feedIdChecker") you actually get an array of all matching elements, but as soon as you call .html it only gets you the first. So to solve your issue we need to loop over all the $(".feedIdChecker")s like so:
$(".feedIdChecker").each(function(i, e) {
var feedID = $(e).html();
$('.output-'+feedID).click(function(){
var postUrl = $("." + feedID + "-EditRegionUrl").html();
console.log(postUrl);
});
});
This will attach the click handler to each of the buttons.
You could use the handlebars.js each/index feature to do this:
<button id="whatever-{{#index}}"
class="output-{{feedId}}">
Output
</button>
I'm assuming you need an answer on how to apply a unique id to each button, not how to bind click handlers to them (which other people have answered anyway)
May this version be quicker and with less code.
$('[class*=output-]').click(function() {
var feedId = this.className.split("-")[1];
var postUrl = $('.EditRegionUrl-' + feedId).html();
alert(postUrl);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="feedIdChecker">1</div>
<div class="EditRegionUrl-1" >URL1</div>
<button class="output-1">Output1</button>
<div class="feedIdChecker">2</div>
<div class="EditRegionUrl-2" >URL2</div>
<button class="output-2">Output2</button>
Can you just put url in the button and a generic class:
<button class="output-{{feedId}} btn-class" data-url="{{url}}">Output</button>
and then
$('.btn-class').click(function(){
console.log($(this).data('url') );
});
Or even just without changing your markup at all
$("button").click(function(){
console.log($(this).prev('div').text());
});