Display array of images in react? - mysql

I am new to react and I want to display array of images in react webpage. The array has statis number of images.
render: function() {
console.log("edit");
return (
<div>
<Button bsStyle="info" id="qslist" onClick={this.show}>View</Button>
<Button bsStyle="info" id="qslist" className="delete" onClick={this.handleDelete}>Delete</Button>
<Button bsStyle="info" id="qslist" className="disable" onClick={this.handleDisable}>Disable</Button>
<Modal show={this.state.showModal} onHide={this.close}>
<Modal.Header closeButton>
<Modal.Title></Modal.Title>
</Modal.Header>
<Modal.Body>
<div id="formdata1">Name:<b>{name}</b></div>
<div id="formdata1">User:<b>{user}</b></div>
<div id="formdata1">Radius:<b>{radius}</b></div>
<div id="formdata1">Status:<b>{status}</b></div>
<div id="formdata1">Type:<b>{type}</b></div>
<div id="formdata1">Latitude:<b>{lat}</b></div>
<div id="formdata1">Longitude:<b>{long}</b></div>
<div id="formdata1">Description:<b>{caption}</b></div>
<div id="formdata1">Schedule:<b>{schedule}</b></div>
<div id="formdata1">Duration:<b>{duration}</b></div>
<div id="formdata1">lshare:<b>{lshare}</b></div>
<div id="formdata1">Id:<b>{listingid}</b></div>
<Image src={imgs} rounded />
</Modal.Body>
<Modal.Footer>
<Button onClick={this.close} bsStyle="info" id="solbutton">Close</Button>
</Modal.Footer>
</Modal>
</div>
);
}
in the above code in image i am trying to display array of images. Currently it is possible to display only one image <Image src={image} rounded/>. How to display many number of images. The array images are in
[
'http://keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg',
'http://wallpaper-gallery.net/images/image/image-13.jpg',
...
]

If you just want to display an array of images (for whatever reason), you can do the following:
In the beginning of the render method (next to the console log) add this:
var images = imgs.map(function(image) {
return (<Image src={image} rounded />);
});
This will map your paths array into an array of Image components (where imgs is an array of paths like you specified).
Then, replace
<Image src={imgs} rounded/>
With
{images}
And that's it.
In case you want some kind of carousel, there are a number of packages available (example), where you can just define something like:
<ImageGallery items={imgs} />

Related

Ionic React too slow to render JSON file containing 100+ objects in IonCard component

I am creating a mobile app with Ionic React. I render multiple IonCards with dynamic data coming from a local JSON file. Actually, I'm mapping through the JSON file. Everything is fine. But it takes a couple of seconds to render all the cards. I want to minimize the loading time. Please help me with how do I optimize the render time and overall performance of the application. The code is below:
//imports...
import data from "../db/data.json";
const Products: React.FC = (filterText) => {
const [searchText, setSearchText] = useState("");
const categories = vocabTopics
//filtering CATEGORIES
.filter((topic) => {return topic.title.toLowerCase().indexOf(searchText.toLowerCase()) >= 0;})
.map((topic) => {
return (
<IonCol size="12" key={topic.id}>
<IonCard mode="md" routerLink={topic.route} className="except-home-screen-card no-margin no-radius-card">
<div className="flex">
<div className="card-img">
<img src={topic.thumbnail}></img>
</div>
<div className="flex-justify-space-b-w">
<div>
<IonCardSubtitle className="except-home-screen-card-subtitle">{topic.subtitle}</IonCardSubtitle>
<IonCardTitle className="except-home-screen-card-title">{topic.title}</IonCardTitle>
</div>
<div>
<IonIcon icon={chevronForwardOutline} className="card-right-icon"/>
</div>
</div>
</div>
</IonCard>
</IonCol>
);
});
return (
<IonPage>
<IonHeader className="ion-no-border">
<IonToolbar className="top-header">
<IonButtons slot="start" className="top-header-icons color-primary">
<IonBackButton defaultHref="home" /></IonButtons>
<div className="top-title-container">
<IonTitle className="ion-text-center v-center">Products</IonTitle>
</div>
</IonToolbar>
</IonHeader>
<IonContent fullscreen className="bg-style">
<div className="center padding-y">
<h1 className="lg-text ion-no-margin equal-padding">Products Categories</h>
<p className="ion-text-center ion-no-margin subtitle">70+ CATEGORIES</p>
</div>
<IonGrid className="my-grid ion-no-padding">
<IonSearchbar spellcheck={true} autocorrect="on" className="searchbar" value={searchText} mode="ios" onIonChange={(e) => setSearchText(e.detail.value!)}></IonSearchbar>
<IonRow className="center-padding">
<div className="card-container fluid">
{categories}
</div>
</IonRow>
</IonGrid>
</IonContent>
</IonPage>
);
};
export default Products;
I suppose 100 Cards are not visible at the same time in a single "view", so the only solution is the "infinite scrolling" and Display/Create them only when them should became visible. (example: https://forum.ionicframework.com/t/infinite-scrolling-of-data-from-the-api/172933)

Select a node with its children based on its class, and turn it into an object

I want to find out how to scrape website data. This is a part of the html that I am interested in. I am using cheerio for finding the data I need.
<td class="col-item-shopdetail">
<div class="shoprate2 text-right hidden-xs">
<div class="currbox-amount">
<span class="item-searchvalue-curr">SGD</span>
<span class="item-searchvalue-rate text-black">42.0000</span>
</div>
<div class="item-inverserate">TWD 100 = SGD 4.2</div>
<div class="rateinfo">
<span class="item-timeframe">12 hours ago</span>
</div>
</div>
<div class="shopdetail text-left">
<div class="item-shop">Al-Aman Exchange</div>
<div class="item-shoplocation">
<span class="item-location1"><span class="icon icon-location3"></span>Bedok</span>
<span class="item-location2"><span class="icon iconfa-train"></span>Bedok </span>
</div>
</div>
</td>
I wish to make "col-item-shopdetail" class as an object and store all class with name "col-item-shopdetail" into an array for access.
So if possible, it will be access like array.item-inverserate or through cheerio selector like
$('.col-item.shopdetail').children[0].children[0].children[1]
I have tried looping through the names of shop and store in an array and use another loop after finish looping the names to find the rates. Then try and match the rates to the name by access same index of the array. However this did not work for unknown reason where each time the rate printed is of different value and index of the same name are different in each try.
This is close to what I want but it does not work:
how to filter cheerio objects in `each` with selector?
In other words, you want an array of objects representing elements having class .col-item-shopdetail and each of those objects should have a property corresponding to the .item-inverserate element they contain ?
You need the map method
my_array = $('.col-item-shopdetail').map(function(i, el) {
// Build an object having only one property being the .item-inverserate text content
return {
itemInverserate: $(el).find('.item-inverserate').text()
};
}).get();
// You can also directly target inverserate nodes
// which will exclude empty entries ('shopdetail' that have no 'inverserate')
// Loop over .item-inverserate elements found
// somewhere in a .col-item-shopdetail
// (beware, space matters)
my_array = $('.col-item-shopdetail .item-inverserate').map(function(i, el) {
// Build an object having only one property being the .item-inverserate text content
return {itemInverserate: $(el).text()};
// Note: If all you need is the inverserate value,
// Why not avoiding an intermediate full object?
// return $(el).text()
}).get();
Since Cheerio developers have built their API based on jQuery with most of the core methods, we can simply test snippets in the browser ...
my_array = $('.col-item-shopdetail').map(function(i, el) {
return {
itemInverserate: $(el).find('.item-inverserate').text()
};
}).get();
console.log(my_array[0].itemInverserate)
my_array_2 = $('.col-item-shopdetail .item-inverserate').map(function(i, el) {
// Build an object having only one property being the .item-inverserate text content
return {itemInverserate: $(el).text()};
}).get();
console.log(my_array_2[0].itemInverserate)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table><tr><td class="col-item-shopdetail">
<div class="shoprate2 text-right hidden-xs">
<div class="currbox-amount">
<span class="item-searchvalue-curr">SGD</span>
<span class="item-searchvalue-rate text-black">42.0000</span>
</div>
<div class="item-inverserate">TWD 100 = SGD 4.2</div>
<div class="rateinfo">
<span class="item-timeframe">12 hours ago</span>
</div>
</div>
<div class="shopdetail text-left">
<div class="item-shop">Al-Aman Exchange</div>
<div class="item-shoplocation">
<span class="item-location1"><span class="icon icon-location3"></span>Bedok</span>
<span class="item-location2"><span class="icon iconfa-train"></span>Bedok </span>
</div>
</div>
</td></tr>
</table>

Getting Images in the form of Grid in AngularJS

How to display all the images in the form of grid, which all will come from back end, so the images are in the dynamic form. and I have to put Description as well on those images, and those Description are also coming from Back End in AngularJS?
If image data is coming in array then you can show image using ng-repeat directive.
Controller
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.imageList = allImage;
});
HTML
<div class="col-md-3" ng-repeat="image in imageList track by $index">
<img src="{{image.imageUrl}}" />
<label> {{image.description}} </label>
</div>
You can use ng-repeat for showing you image with description like:
<li class="col-sm-3" ng-repeat="product in productList">
<img src={{product.imageUrl}} />
<label>{{product.description}}</label>
</li>
Here is the documentation

Knockout Clone Whole Item In foreach

I am trying to clone elements when clicking a button. I was trying to use ko.toJS. On page load it works fine, but when I want clone the items, it is unable to bind the items (like, value, Text, etc.).
Here is the HTML:
<div class="stockItems-inner" data-bind="foreach: StockItems">
<div data-bind="if: Type=='Input'">
<div class="stock_container_input">
<input type="text" data-bind="value: Value" />
</div>
</div>
<div data-bind="if: Type=='Radio'">
<div class="stock_container_control">
<div data-bind="foreach: Options">
<div class="stockLbl">
<input type="radio" data-bind="text: Text, checked:$parent.Value, attr:{'id':Id, 'name': $parent.Text, 'value': Value}" />
<label data-bind="attr:{'for':Id}, text: Text"></label>
</div>
</div>
</div>
</div>
</div>
<div class="addItem">
<button type="button" data-bind="click: CloneItem"><img src="images/add.png" alt="" /></button>
</div>
The View Model:
ConfigurationStockViewModel = function() {
var self = this;
this.StockItems = ko.observableArray();
this.ApplyData = function(data){
self.StockItems(data.Items);
}
this.CloneItem = function(StockItems){
self.StockItems.push(ko.toJS(StockItems));
};
};
When clicking the button, an error is thrown: Unable to process binding. I am using JSON data for binding.
Not exactly sure what end result you want without working code, but sounds like you want to clone the last item in array and add to array?
If so, I think you have an error - your add button click binding will never pass anything to the function you defined, since it is outside the foreach. You need something like this:
this.CloneItem = function() {
var toClone = self.StockItems()[self.StockItems().length - 1]
self.StockItems.push(toClone);
};
Here is a simplified example without radio buttons, etc:
http://jsfiddle.net/5J47L/

Toggle specific div and change img jquery

I have a problem with toggle on this list:
<div id="list">
<div id="segment"> // <--- when clicked, toggle segm_content and opener
<div id="opener">
<img src="images/open.png" /> // changes when toggled
</div>
<div id="segm_content">
// content to hide/show
</div>
</div>
<div id="segment"> // <--- when clicked, toggle segm_content and opener
<div id="opener">
<img src="images/open.png" /> // changes when toggled
</div>
<div id="segm_content">
// content to hide/show
</div>
</div>
... //and so on
</div>
I want clicked "#segment" to toggle child *"#segm_content"* and change img in "#opener".
I made it working with this code:
$('#segment').toggle(function() {
$('#opener').html('<img src="images/open.png"/>');
$('#segm_content').hide(500);
}, function() {
$('#opener').html('<img src="images/close.png"/>');
$('#segm_content').show(500);
});
But I can't figure out how to do it only for one "#segment" at a time.
This code toggles everything, which I don't want.
I am stuck at this point, any suggestions please?
Many thanks!
I really wouldn't recommend this. The point of an id is to reference a unique element. If you want to select multiple elements, you should define a class instead and have jQuery call that. Multiple ids is invalid HTML. But you could, per sé, do this by using changing your jQuery code to the following.
(Here is my jsFiddle: http://jsfiddle.net/KzVmK/)
$('[id="segment"]').toggle(
function(){
$(this).find('[id="opener"]').html('<img src="open.png" alt="Close" />');
$(this).find('[id="segm_content"]').hide(500);
},
function(){
$(this).find('[id="opener"]').html('<img src="close.png" alt="Open" />');
$(this).find('[id="segm_content"]').show(500);
}
);​
Again, let me stress again that this is a bad idea, because you will not have unique id selectors in your document. This is really bad practice. There are times when you will want to select an individual element in the DOM and this will make that next to impossible. I would highly advise you to define a class for the elements (you can still define CSS classes, e.g. <div class="opener my-class" /> or <div class="segm_content my-class" />).
(Also, a helpful tip with this code: rather than populating the HTML elements with the same image that is also in the jQuery code [which is redundant], leave the <div id="opener" /> elements empty. Then, right after you define the toggle function, run the click event, like so: $('[id="$segment"]').toggle(...).click();
http://jsfiddle.net/XPXBv/).
General Theme Settings
Back-Ground Color
Text Color
<div class="Settings" id="GTSettings">
<h3 class="SettingsTitle"><a class="toggle" ><img src="${appThemePath}/images/toggle-collapse-light.gif" alt="" /></a>Content Theme Settings</h3>
<div class="options">
<table>
<tr>
<td><h4>Back-Ground Color</h4></td>
<td><input type="text" id="body-backGroundColor" class="themeselector" readonly="readonly"></td>
</tr>
<tr>
<td><h4>Text Color</h4></td>
<td><input type="text" id="body-fontColor" class="themeselector" readonly="readonly"></td>
</tr>
</table>
</div>
</div>
$(document).ready(function(){
$(".options").hide();
$(".SettingsTitle").click(function(e) {
var appThemePath = $("#appThemePath").text();
var closeMenuImg = appThemePath+'/images/toggle-collapse-light.gif';
var openMenuImg = appThemePath+'/images/toggle-collapse-dark.gif';
var elem = $(this).next('.options');
$('.options').not(elem).hide('fast');
$('.SettingsTitle').not($(this)).parent().children("h3").children("a.toggle").children("img").attr('src', closeMenuImg);
elem.toggle('fast');
var targetImg = $(this).parent().children("h3").children("a.toggle").children("img").attr('src') === closeMenuImg ? openMenuImg : closeMenuImg;
$(this).parent().children("h3").children("a.toggle").children("img").attr('src', targetImg);
});
});