How to get card value after clicking in loop - javascript

I have this script for create cards based on list using for loop:
<script>
$(document).ready(function () {
var mokData = [
{ category: "Material", id: '1', name: 'Brakedown of machine' },
{ category: "Material", id: '2', name: 'Brakedown of machine' },
{ category: "Tool", id: '3', name: 'Brakedown of machine' },
{ category: "Tool", id: '4', name: 'Brakedown of line' },
{ category: "Tool", id: '5', name: 'Brakedown of machine' },
{ category: "Tool", id: '6', name: 'Brakedown of line' },
{ category: "Tool", id: '7', name: 'Brakedown of machine' },
{ category: "Tool", id: '8', name: 'Brakedown of line' }
];
$.each(mokData, function (i) {
var templateString = '<article class="card"><h2>' + mokData[i].category + '</h2><p>' + mokData[i].name + '</p><p>' + mokData[i].id + '</p><button id="tes">Start</button></article>';
$('#test12').append(templateString);
})
$("#test12 button").on("click", function () {
alert();
});
});
</script>
Now I need to get the value when the button clicked

In this line:
$('#test12').append(templateString);
JQuery is returning an element which you can directly add an event listener to. You can do something like this:
const element = $('#test12').append(templateString);
const thisData = mokData[i];
$(element).click(function() {
console.log(thisData); //mock data related to the item you've just clicked
});
In the method above, you don't need to attach any additional data to the DOM, you can just reference what you already have access to.

To achieve this you can attach a click handler to all button elements and use the reference to the clicked element, available through the Event object passed to the handler function, to retrieve the content from the HTML related to that button. Try this:
jQuery($ => {
var mokData = [{category:"Material",id:'1',name:'Brakedown of machine'},{category:"Material",id:'2',name:'Brakedown of machine'},{category:"Tool",id:'3',name:'Brakedown of machine'},{category:"Tool",id:'4',name:'Brakedown of line'},{category:"Tool",id:'5',name:'Brakedown of machine'},{category:"Tool",id:'6',name:'Brakedown of line'},{category:"Tool",id:'7',name:'Brakedown of machine'},{category:"Tool",id:'8',name:'Brakedown of line'}]
// create HTML from array of objects
let html = mokData.map(o => `<article class="card"><h2>${o.category}</h2><p>${o.name}</p><p>${o.id}</p><button>Start</button></article>`);
$('#test12').append(html);
// handle button click and retrieve nearest id
$("#test12 button").on("click", e => {
let $btn = $(e.target);
let id = $btn.closest('.card').find('p:eq(1)').text();
console.log(id);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="test12"></div>
Note that I removed id="tes" from the button in the HTML you create as that will result in repeated id values which is invalid - they must be unique within the DOM.

Related

Getting id or name of folder in fuelux tree

I'm trying to get the id or name of the selected folder in a fuelux tree but couldnt manage to get it done.
My tree is a classic folder/file type tree and I want to be able to see the id of the folder when I click on a file.
this is my datasource for tree
var treeDataSource = new DataSourceTree({
data: [
{ name: 'Elektronik Belgelerim', type: 'folder', 'icon-class': 'blue', additionalParameters: { id: 'F1' } },
{ name: 'Gelen Kutusu', type: 'folder', 'icon-class': 'blue', additionalParameters: { id: 'F2' } },
{ name: 'Giden Kutusu', type: 'folder', 'icon-class': 'blue', additionalParameters: { id: 'F3' } },
{ name: 'Çöp Kutusu', type: 'folder','icon-class':'green', additionalParameters: { id: 'I1' } },
//{ name: 'Çöp Kutusu', type: 'item', 'icon-class': 'success', additionalParameters: { id: 'F4' } },
//{ name: 'Reports', type: 'item', additionalParameters: { id: 'I1' } },
//{ name: 'Finance', type: 'item', additionalParameters: { id: 'I2' } }
],
delay: 400
});
js function for tree begins like this inside tree-custom.js
var e = function (e, i) {
this.$element = t(e), this.options = t.extend({}, t.fn.tree.defaults, i), this.$element.on("click", ".tree-item", t.proxy(function (t) {
this.selectItem(t.currentTarget)
}, this)), this.$element.on("click", ".tree-folder-header", t.proxy(function (t) {
this.selectFolder(t.currentTarget)
}, this)), this.render()
};
and this is where I add the links under folders again inside trree-custom.js. Very primitive I know but that's all I can do with my current skillset. The part I added is between quotes. Rest came with beyondadmin theme and looks like usual fuelux.
selectFolder: function (e) {
//alert("testselectFolder");
//
//alert($('#myTree').tree({ dataSource: dataSource }));
var i, n, r, o = t(e),
s = o.parent(),
a = s.find(".tree-folder-content"),
l = a.eq(0);
//-----------------------------------------------
var li = $('<li>');
var TcgbLink = $('<a href=/E-Belge/Main/Folder/Inbox/?Type=1&DocumentTypeId=3>e-TCGB</div>' +"</br>");
var FaturaLink = $('<a href=/E-Belge/Main/Folder/Inbox/?Type=1&DocumentTypeId=4>e-Fatura</div>' + "</br>");
var Dolasim = $('<a href=>e-Dolasim Belgesi</div>');
li.append(FaturaLink);
a.append(li);
li.append(TcgbLink);
a.append(li);
li.append(Dolasim);
a.append(li);
//-----------------------------------------------
o.find(".fa.fa-folder").length ? (i = "opened", n = ".fa.fa-folder", r = "fa fa-folder-open", l.show(), a.children().length || this.populate(o)) : (i = "closed", n = ".fa.fa-folder-open", r = "fa fa-folder", l.hide(), this.options.cacheItems || l.empty()), s.find(n).eq(0).removeClass("fa fa-folder fa-folder-open").addClass(r), this.$element.trigger(i, o.data())
},
Now these links are being generated under all 4 folders. I want to be able to get the id (or name, preferably Id) of the folder so I can assign new Type parameters to querystring.
So far I tried to reach the id with this.data.id to no avail.
Instead of injecting the folder's children in the selectFolder callback, it is recommended to add the children via the dataSource callback (as in this example code: http://getfuelux.com/javascript.html#tree-usage-javascript).
The first argument to the dataSource is the "parent data" when you click on a tree node (with the second argument being the callback that you send the new array of child data).
This way you can use the selected event for getting your ID, because it gets the jQuery data passed to it.

Dynamically add attributes as object properties

I'm working on bootstrap-multiselect, I'm trying to add data attributes in the dataprovider method.
Current
var options = [
{label: 'Option 1', title: 'Option 1', value: '1', selected: true},
{label: 'Option 2', title: 'Option 2', value: '2'}];
In the code it maps these an <option> tag like so:
$tag = $('<option/>').attr({
value: option.value,
label: option.label || option.value,
title: option.title,
selected: !!option.selected,
disabled: !!option.disabled
});
Desired
var options =[
{
"label": "Item 1",
"value": 1,
"selected": false,
"attributes": [
{
"some-attribute": 10001
},
{
"another-attribute": "false"
}
]
}
]
So it will render on the HTML element as data-some-attribute="10001" data-another-attribute="false".
I started out adding this to the code (which I know won't work):
$tag = $('<option/>').attr({
value: option.value,
label: option.label || option.value,
title: option.title,
selected: !!option.selected,
disabled: !!option.disabled,
forEach(option.attributes, function(attribute){
})
});
The problem of course is you can't add a loop as an objects properties.
Once this is working I can add a pull request to the repository. I did ask a question on the repo but decided to try and tackle it myself Issue #592
Any ideas?
I would suggest changing attributes from an array to an object, since attribute names should be unique. It also simplifies how you would get the data attributes on the element.
var attributes = {
value: option.value,
label: option.label || option.value,
title: option.title,
selected: !!option.selected,
disabled: !!option.disabled
};
for (key in option.attributes) {
attributes['data-' + key] = option.attributes[key];
}
$tag = $('<option/>').attr(attributes);
If you wanted to keep it as an array, you can do the following:
var attributes = {
value: option.value,
label: option.label || option.value,
title: option.title,
selected: !!option.selected,
disabled: !!option.disabled
};
for (var i = 0; i < option.attributes.length; i++) {
var key = Object.keys(option.attributes[i])[0],
val = option.attributes[i][key];
attributes['data-' + key] = val;
}
$tag = $('<option/>').attr(attributes);
Doing this, however, provides no benefit and introduces complexity. If each object can have multiple keys, the code will need to change further.
You need to create the element first then add the attributes to it.
So your code should be like this:
var options = [{
"label": "Item 1",
"value": 1,
"selected": false,
"attributes": [{
"some-attribute": 10001
}, {
"another-attribute": "false"
}]
}]
console.log(options.length);
$.each(options, function(option) {
var $tag = $('<option/>').attr({
value: options[option].value,
label: options[option].label || options[option].value,
title: options[option].title,
selected: options[option].selected,
disabled: options[option].disabled
});
console.dir(option);
$.each(options[option].attributes, function(att) {
$tag.attr("data" + Object.keys(att)[0], att[0])
});
$("#mySelect").append($tag);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="mySelect">
</select>

custom angular filter used on ng-option leaves blank options

I am trying to filter out some options in a select element using angular.js. The problem is that for every item in the model that doesn't meet the filter criteria I get a blank option element in the select.
My questions are:
How can I fix the custom filter to remove the empty options?
Is there a way to modify the value of my ng-options directive to perform this filter more declaratively in the markup?
The code is below and you can also find it at http://jsfiddle.net/G4qkW/
<div ng-app="myApp">
<div ng-controller="myController">
<select ng-model="militaryBranches" ng-options="m as m | coreBranches for m in militaryBranches">
<option value="">Select Military Branch</option>
</select>
</div>
function myController($scope) {
$scope.militaryBranches = [{
BranchId: '1',
Name: 'Air Force'
},{
BranchId: '2',
Name: 'Army'
},{
BranchId: '3',
Name: 'Coast Guard'
},{
BranchId: '4',
Name: 'Marines'
},{
BranchId: '5',
Name: 'Navy'
},{
BranchId: '6',
Name: 'National Guard 1'
},{
BranchId: '7',
Name: 'National Guard 2'
},{
BranchId: '8',
Name: 'Some Other Branch'
}];
}
var app = angular.module('myApp', []);
app.filter('coreBranches', function() {
return function(item) {
if (item.BranchId < 6) {
return item.Name;
}
};
});
I have edited your fiddle: http://jsfiddle.net/G4qkW/5/
I guess you want the branches filtered out, not to display their names. You need to apply the filter to the collection, not to the name:
m.BranchId as m.Name for m in militaryBranches | coreBranches
To make this work, edit the filter like this:
app.filter('coreBranches',
function () {
return function (items) {
var filtered = [];
angular.forEach(items, function (item) {
if (item.BranchId < 6) {
filtered.push(item);
}
});
return filtered;
}
});

How to get the id on right click context menu in dojo Tree?

I want to get the node id of Dojo's tree on context menu click.
I'm making a tree in Dojo like this. Here is the id - the first param.
this.setData(
[
{ id: '5', name:'root' , type:'continent' },
{ id: '6', name:'catalog 1', parent: '5' , type:'continent' },
{ id: '7', name:'catalog 2', parent: '5' , type:'continent' },
{ id: '8', name:'catalog 2.1', parent: '7' , type:'continent' },
{ id: '9', name:'child Catalog', parent: '8' , type:'continent' },
{ id: '10', name:'catalog 4', parent: '5' , type:'continent' } ]);
Here is my tree and menu init functions.
So, when I click with the right button on the tree - there is a context menu with a button. When I click that button - it triggers the onClick function. I want to receive that id.
<script>
function createMyTree()
{
var tree = new dijit.Tree({
model: myModel,
id: 'contextMenu'
});
tree.placeAt("myTree", "last");
tree.startup();
pMenu = new dijit.Menu({
targetNodeIds:["contextMenu"]
});
pMenu.addChild(new dijit.MenuItem({
label:"Delete",
iconClass:"dijitEditorIcon dijitEditorIconDelete",
onClick: function(){
/// HERE I WANT MY id
}
}));
pMenu.startup();
}
How can I do that?
I haven't used dojo before, but I think you should use the contextmeu event over onclick. From that you can get the target or relatedTarget and checking it with button property (the type of mouse button pressed; probably 2).
If that doesn't gives you a valid element, you can use document.elementFromPoint(x,y) from the event.screenX and event.screenY to get the valid element.
I found it..
Thanks guys. If you have better suggestions please share it. :)
var selectedObject = tree.get("selectedItems")[0];
console.log("the id what I need", selectedObject.id);
selector: '.dijitTreeNode' in Menu config options.

items not within the <ul></ul>

I create a menu with a javascript object and jquery. I have certain items that needs to be in the <ul></ul> but instead they're beneath it.
http://jsfiddle.net/MWBt6/
I have 'Index' for example. In there I want to append a list of items.
I know the category id is 0 and the item id is 2, i stored those things in the data attribute.
Now how can I append a ul to that one?
That's not how append works. You need to create the elements on their own. Here:
var loadPath = "resources/books/book1/";
var menu = {
data: [{
name: "the book",
id: 0,
items: [{
name: "Introduction",
id: 0,
target: "inleiding.html"
}, {
name: "Content",
id: 1
}, {
name: "Index",
id: 2
}]
}, {
name: "my stuff",
id: 1,
items: [{
name: "Notes",
id: 0
}, {
name: "Marks",
id: 1
}]
}, {
name: "other",
id: 2,
items: [{
name: "Search",
id: 0
}, {
name: "Continue Reading",
id: 1
}]
}]
}
$(document).ready(function() {
var $menu = $('#menu');
for(var i = 0; i < menu.data.length; i++) {
var categorie = menu.data[i];
var categorieName = categorie.name;
var categorieId = categorie.id;
var items = categorie.items;
console.log("categorieName: " + categorieName);
var list = $('<ul>');
for(var j = 0; j < items.length; j++) {
var itemId = items[j].id;
list.append($('<li>').attr('data-itemId', itemId).text(items[j].name));
}
$menu.append(
$('<li>').attr('data-categorieId', categorieId).append(categorieName, list)
);
}
});​
Here's the updated jsFiddle.
You are trying to append as if the DOM is a text editor. You can't append the beginning of an element with it's opening tag, then later close that element with an append of a closing tag. Only full valid elements can be inserted into the DOM.
Instead, build an html string, then only make one append after the string is completed. This method is far more efficient than doing multiple appends also
Working demo: http://jsfiddle.net/MWBt6/3/

Categories