adding items with ngFor with multiple arrays - javascript

Im trying to list some data from 2 different arrays - I need to keep the arrays seperate so i can differenciate between the data. I also need to add a class on items from the first array.
I've tried:
<div class="divInput" id="divC">
<div class="divTextInput">
<input /><button>Add</button>
</div>
<div id="CWrapper" class="tableWrapper">
<div class="cell" *ngFor="let c1 of data.c1">
<p title={{c1}}>{{c1}}</p><span></span>
</div>
<div class="cell kle" *ngFor="let c2 of data.c2">
<img src={{imagePath}}>
<p title={{c2}}>{{c2}}</p><span></span>
</div>
</div>
</div>
The kle class doesnt add any css, it's just there so i can differentiate between the two, and do trigger events.
Where the data class is:
class Data {
c1: string[];
c2: string[];
}
Adding to the array with:
$('#divC .divTextInput button').on('click', (ev) => {
let button = $(ev.currentTarget);
let input = button.prev();
if (input.val()) {
this.data.c1.push(<string>input.val());
this.data.c2.push(<string>input.val());
}
});
When i add a string to c2, it adds it to the html, but when i add a string to c1 it doesnt add to the html (Only div with class="cell kle" is added)
It adds the data that initially is in the array, but not when i add dynamically
If i log the arrays, they both have the added string.
-- Update --
It works if the arrays arent in a class.

Related

Javascript - Use array values dynamically in HTML

My end result is supposed to be a list of objects in html. Bootstrap behind this. I'd like for the list to be created dynamically so I don't have to manually create all the divs because I don't know how many there will be. Here's what I have.
I have an array similar to this:
activities =
[
{
"activityOwner": "Raymond Carlson",
"activityDesc": "Complete all the steps from Getting Started wizard"
},
{
"activityOwner": "Flopsy McDoogal",
"activityDesc": "Called interested in March fundraising Sponsorship"
},
{
"activityOwner": "Gary Busy",
"activityDesc": "Get approval for price quote"
}
]
This is the first part where I'm not sure what to do. I can assign the element ids individually for my html like this but what I'd like to do is count how many elements are in my array and create these for me. I won't know how many there are to make these manually. I'm sure there needs to be a loop but I couldn't figure it out.
document.getElementById('activityowner0').innerHTML = activities[0].activityOwner;
document.getElementById('activitydesc0').innerHTML = activities[0].activityDesc;
document.getElementById('activityowner1').innerHTML = activities[1].activityOwner;
document.getElementById('activitydesc1').innerHTML = activities[1].activityDesc;
document.getElementById('activityowner2').innerHTML = activities[2].activityOwner;
document.getElementById('activitydesc2').innerHTML = activities[2].activityDesc;
etc.
etc.
And then...once I have that part, I'd like to know how to create my html divs dynamically based on how many elements are in my array. Again, right now I don't know how many there are so I'm having to create a bunch of these and then have extras if I have too many.
<div class="container">
<div class="row"></div>
<div class="qa-message-list" id="wallmessages">
<br>
<div class="message-item" id="m0">
<div class="message-inner">
<div class="message-head clearfix">
<div class="user-detail">
<h5 class="handle">
<p id='activityowner0'></p>
</h5>
<div class="post-meta"></div>
</div>
</div>
<div class="qa-message-content">
<p id='activitydesc0'></p>
</div>
</div>
</div>
I know this is a big ask so just pointing me in the right direction would be very helpful. I hope my question was clear and I appreciate it.
One way for you to achieve this would be to loop through the objects in your activities array. From there you can use a HTML template to store the base HTML structure which you can clone and update with the values of each object before you append it to the DOM.
In addition, an important thing to note when generating repeated content in a loop: never use id attributes. You will either end up with duplicates, which is invalid as id need to be unique, or you'll end up with ugly code generating incremental/random id at runtime which is unnecessary. Use classes instead.
Here's a working example:
const activities = [{ "activityOwner": "Raymond Carlson", "activityDesc": "Complete all the steps from Getting Started wizard"}, {"activityOwner": "Flopsy McDoogal","activityDesc": "Called interested in March fundraising Sponsorship" }, { "activityOwner": "Gary Busy", "activityDesc": "Get approval for price quote" }]
const html = activities.map(obj => {
let item = document.querySelector('#template').innerHTML;
item = item.replace('{owner}', obj.activityOwner);
item = item.replace('{desc}', obj.activityDesc);
return item;
});
document.querySelector('#list').innerHTML = html.join('');
<div id="list"></div>
<template id="template">
<div class="container">
<div class="row"></div>
<div class="qa-message-list">
<div class="message-item">
<div class="message-inner">
<div class="message-head clearfix">
<div class="user-detail">
<h5 class="handle">
<p class="activityowner">{owner}</p>
</h5>
<div class="post-meta"></div>
</div>
</div>
<div class="qa-message-content">
<p class="activitydesc">{desc}</p>
</div>
</div>
</div>
</div>
</div>
</template>

rendering list of objects in react/mobx

i have a list of objects in my jsx class. Let's assume it's a fixed list of objects for now
versions = [
{owner: "luca", date: "today", fw: "00"},
{owner: "thomas", date: "tomorrow", fw: "00"},
{owner: "peter", date: "yesterday", fW: "00"},];
i'm trying to render the values of these objects in nested div elements on my webpage. basically it's a panel of rows that i represent as divs. here's the html for it
<div className="fc-revisions-sidebar revisions-panel flex-vertical flex-grow-1">
<div className="fc-revisions-sidebar-header fc-revisions-sidebar-header-bg-color-brand">
<div className="fc-revisions-sidebar-title">Version history</div>
</div>
<div className="fc-revisions-sidebar-revisions-list-container">
<div className="fc-revisions-sidebar-revisions-list">
<div role="rowgroup">
<div className="fc-revisions-collapsible-panel" role="button">
<div className="fc-revisions-collapsible-panel-container">
<div className="fc-revisions-row fc-revisions-row-selected" role="row" aria-selected="true" aria-level="1">
<div className="fc-revisions-row-content-wrapper">
<div className="fc-revisions-row-header fc-row-content">
<div className="fc-revisions-row-text-box" rows="1" maxLength="80" aria-multiline="false">
**{version.date}**
</div>
</div>
<div className="fc-revisions-row-content fc-row-content" role="presentation">
<div className="fc-revisions-row-collaborator-list">
<div className="fc-revisions-row-collaborator">
<span className="fc-versions-rown-collaborators-label">Created by **{version.owner}**</span>
<span className="fc-revisions-row-collaborator-name">**{version.fw}**</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
i'm not sure how to implement this in my component class!!
starting from the first div after this one
<div role="rowgroup">
my html code to create each row in the panel starts.
I want to iterate over the objects in my list and create/fill each row in my panel with the right data from that list
I've tried a dozen different ways but nothing is showing up on my webpage. I just don't understand how to iterate over the list of objects in 'versions' and create/fill the panel in progress.
Let assume you have array of objects declared inside render using const. You can iterate the array either using .map, .forEach, for loop etc. In your case I would prefer .map for iteration because map returns new array. So inside the map construct jsx elements and return them.
Now, returned jsx elements will be placed in versionItems array. You can just call that with {} like expression in render return.
render(){
const versions = [
{owner: "luca", date: "today", fw: "00"},
{owner: "thomas", date: "tomorrow", fw: "00"},
{owner: "peter", date: "yesterday", fW: "00"},];
const versionItems = versions.map((item, index) => {
return (
<div key={"key"+index} role="rowgroup">
//just get all your property values here using item.owner, item.date etc
</div>
)
});
return(
<div>
{versionItems}
</div>
)
}
Iteration is normally done by maping an array of values to an array of components. Something like this:
versions = [ ... ]
return (
<div>
<div>Version History</div>
{
versions.map(version =>
<div key={version.date}>
{version.date}
</div>
)
}
</div>
)
Note that for Reacts reconciliation to work properly when potentially re-rendering with a new array of values, the outer element in the array should have a unique key attribute so that React quickly can recognize any removed or added values in the array on the next render.

Vue JS send data from v-for on button click

I'm new to Vue JS, and i'm having a little problem
i'm looping through an array and i have a button inside the div that i'm looping with
the idea is to get the data of the specified data after the click event
for example let's say i have this array numbers: [1,2,3,4,5] and i'm looping through it like this
<div v-for="number in numbers">
<p>{{ number }}</p>
<button v-on:click="getTheSelectedOne"> Get The Value </button>
</div>
i tried doing so
<button v-on:click="getTheValueOfTheSelectedOne(number)"> Get The Value </button>
but i got an error,
how can i achieve such a result ?
<div v-for="number in numbers">
Should be:
<div v-for="(number, index) in numbers" :key="index">
The following:
<button v-on:click="getTheSelectedOne"> Get The Value </button>
Should be:
<button v-on:click="getTheSelectedOne(number)"> Get The Value </button>
And you must have that method defined:
methods: {
getTheSelectedOne (number) {
// then number will be the number
console.log(number)
}
}

I have a 100 button, click each button to display its corresponding bomb box, With javascript and angular

a button corresponding to a prompt box,each box is different shells;Although implements the desired function, but my code is too complicated, and that there is no simple way. how can I do? This is my code
<--html button-->
button1
button2
...
button100
<--html pop box-->
<div class="note1" style="display:none;">
<img class="title-css" src="note1.png">
<p class="one">note1</p>
</div>
...
<div class="note100" style="display:none;">
<img class="title-css" src="note100.png">
<p class="one">note100</p>
</div>
<--angular js-->
$scope.showRulePop = function(index) {
for(var i=1;i<=8;i++) {
$('.note'+i).hide();
}
$('.note'+index).show();
};
Well first of all, don't use jQuery, unless your in the directive level of angular jQuery have nothing to do there.
First let's get rid of the links part using a simple ng-repeat :
<--html button-->
<div ng-repeat="button in buttons">
{{button.label[i]}}
</div>
// JS in the controller
$scope.buttons = [{
label:'button1'
},{label:'button2'}];
As you can see i declare in the javascript all your buttons and i just loop over it.
Now the "bombox" or whatever it is let's make it a simple template :
<div class="{{currentnote.class}}" ng-if="currentNote">
<img class="title-css" src="{{currentNote.img}}">
<p class="one">{{currentNote.content}}</p>
</div>
// and use ng-repeat for the eight first when there is no button selected
<!-- show 1 to 8 if note current note selected -->
<div ng-repeat="button in buttons1To8" ng-if="!currentNote">
<div class="{{button.note.class}}">
<img class="title-css" src="{{button.note.img}}">
<p class="one">{{button.note.content}}</p>
</div>
</div>
// JS
$scope.buttons = [{
label:'button1'
note:{class:'note1', img:'note1.png', content:'note1'//assuming no HTML or you' ll need something more
}},{label:'button2', note:{...}}, ...];
$scope.showRulePop = function(index){
$scope.currentNote = $scope.buttons[index].note;
}
$scope.buttons1To8 = $scope.buttons.slice(0, 8);//0 to 7 in fact
That's all, no need of jQuery.

jQuery pass dynamically created variable to another function

I have form partial in Rails, laid out like so:
<div class"row">
<div class="col-md-6" id="top_level">
</div>
</div>
<div class"row">
<div class="col-md-2" id="sub_category1">
</div>
</div>
<div class"row">
<div class="col-md-2" id="sub_category2">
</div>
</div>
<div class"row">
<div class="col-md-2" id="sub_category3">
</div>
</div>
<div class"row">
<div class="col-md-3" id="sub_category4">
</div>
</div>
<div class"row">
<div class="col-md-3" id="sub_category5">
</div>
</div>
It is for selecting categories and sub-categories of items.
listings_controller:
def new
#product_listing = Listing.new
#product_ = Product.find(params[:product_id])
# gon.categories = EbayCategory.all
gon.top_level = EbayCategory.top_level
end
In the model:
scope :top_level, -> { where('category_id = parent_id').order(:id) }
Each category record (17989 of them) has a unique category_id, and a parent_id. As indicated above, the top level category_id = the parent_id for the same record. All the subcategories have their own category_ids, which are the parent_ids of the next level down, and so on, varying between 1 and 5 sub-levels.
I've tried a cascade of view files, which works fine (it renders the correct categories and sub-categories) but I can't pass the listing id that way because I don't know how to transmit 2 ids (one for the parent category, one for the listing id) through the params hash using the link_to url helper, so I lose the id for the listing I'm trying to create while navigating all the sub-categories.
So I'm trying it with jQuery, using the Gon gem. Not only does this mean loading the entire db table (about 7 MB, once I un-comment the line for use in level 2 thru 5) into ram, but I can't figure out how to pass the category_id from the dynamically created top_level list when one of its elements is clicked. There are many levels to go, but right now I'm just trying to console.log the category_id for ONE level, so I can see that it's registering. So far unsuccessful, after trying many different syntaxes and methods, of which this is the latest:
<script type="text/javascript">
$(gon.top_level).each(function(){
$("#top_level").append('<h5>' + this.main_category + " >" + '</h5>').data($(this).category_id);
})
$("#top_level").on('click', 'a', function(){
console.log($(this).data());
});
</script>
...returns
Object {}
to the console.
Any suggestions on how to store ids dynamically with the text category titles?
$('gon.top_level').each(function(){
var lnk = $('<h5>' + this.main_category + " >" + '</h5>')
.find('a').data({'category':$(this).category_id,'anotherKey':'value'});
$("#top_level").append(lnk);
});
$("#top_level").on('click', 'a', function(){
console.log($(this).data('category'));
console.log($(this).data('anotherKey'));
});
To set data use $(elment).data({key:value});
To get data use $(elment).data(key);

Categories

Resources