React renderDOM in multiple spots on same page? - html

I want react to render a DOM at multiple spots on my page. For example, if there's the class (.react-container), I want it to render the react component.
How can I do this if there are multiple spots on the page?
IMPORTANT: ArrayOne amount changes depending on where it's rendered.
APP.JS FILE
const App = () => {
return (
<div>
<div className="react-container">
{
ArrayOne.map(item=> (
<div className={
clsx({
'card': true,
'card-visible': state
})} >
<h2>{item.title}</h2>
<p>{item.text}</p>
</div>
))
}
</div>
</div>
);
};
INDEX.JS FILE
for (const el of document.querySelectorAll(".react-container")) {
ReactDOM.render(<App/>, el);
}
Code above is not running how I would like it to. It gives me two rows of only 1 card. When it should be 4 cards on row one and 1 card on row two. Console shows:
run query selector
running (4)
run query selector
running(1)
run query selector
running(1)
When I want it to do.
run query selector
running(4)
run query selector
running(1)

Interesting code. But i believe you are mixing some stuff.
get the layout working first, since seems you are not using React to do the layout.
<div>
<div className="react-container"></div>
<div className="react-container"></div>
<div className="react-container"></div>
<div className="react-container"></div>
</div>
render them into it with your lines.
for (const el of document.querySelectorAll(".react-container")) {
ReactDOM.render(<App/>, el);
}
Keep in mind, if you want to use your rest of code, you need to render it into a root, as in a typical React setup.
<div id="root"></div>
So pick one approach, either render once, but let react control everything underneath it, or render multiple times. You can't do both.

Related

Jquery change css class from variable

For my site, I code a button allowing to change the css of a class present in a div card. My button is located in the card-footer. Having several cards, I can't / don't think to retrieve the element with an id (as there will be X times the same ID)
In order to circumvent this system, I therefore use a parentElement which goes up to the div card
<div class="card">
<div class="card-body">
<p class="change">Change one</p>
<p class="change">Change two</p>
<p class="change">Change three</p>
</div>
<div class="card-footer">
<i id="updateData">change</i>
</div>
</div>
jQuery($ => {
$('#updateData').click(e => {
var element = e.target.parentElement.parentElement;
$('.change').css('display','none');
});
});
I would like to indicate that only the class "changes" present in my element variable and not all the classes in the page.
I don't know how to add a variable to my ".css" command, do you know how ?
Thanks in advance !
First of all since you will have multiple elements with same id that means that you should not use ID and use class instead. Id is meant to be unique. So yours id="updateData" should become class="updateData". Now you can grab all of those buttons and assign event to all of them instead of just first like you were by using id selector.
$('.updateData').click(e=> {});
Next in order to be able to use clicked element in jQuery way convert from arrow function to regular anonymous function since arrow function overrides this keyword. And now you can use jQuery to hide like
$('.updateData').click(function() {
element = $(this).parent().parent();
element.hide();
});
If you want more precise selection to hide only .change elements use
$('.updateData').click(function() {
element = $(this).parent().parent();
element.find(".change").hide();
});
Not bad, but more efficient, when you have multiple click targets, is delegation:
$(document).on("click", ".updateData", function() { ... });
Also .hide() is convenient, but rather then "change the css of a class" add a class "hidden" or something! In best case the class further describes what the element is. CSS is just on top.

How to trigger click event on a div element and show its neighbour element JQUERY

I have a lot of divs, they are the same but the data are differen(I use variable(array of objs) and for loop) but these details aren't important
<div class="item_wrapper">
<div class="item_wrapper_info">
<div class="left-line"></div>
<div class="subject">1</div> <== click here
</div>
<div class="additional_info"> <== display this block
some text
</div>
</div>
I want to achieve this:
If I click .item_wrapper_info div then I want to show .additional_info div
It should be probably done using this keyword.
If I click . item_wrapper_info block I want to find a div with the class name of . additional_info and make display = flex but I don't know how to trigger exactly its . additional_info div.
Probably I can click on .item_wrapper_info > . subject and then show its next neighbour
SOLUTION:
$(document).ready(() => {
$(".item_wrapper").click(function(){
var index = $(".item_wrapper").index(this); get index of a certain clicked .item_wrapper element on my page
$('.additional_info').eq(index).toggle(); using .eq toggle that certain element
});
})
It works for me
I haven't tested this code. Feel free to test it in a runnable snippet.
$(document).ready(() => {
$(".item_wrapper").click(function () {
var index = $(".item_wrapper").index(this)
$('.additional_info').eq(index).css("display","flex");
});
});

Load new jsx renders into existing Div

My goal is to render different pages with different layouts to one div on my index page. The idea is that only one div ("create-focus") changes and I want the other pieces to only have to load once.
This is a proof-of-concept so everything that I am building is local (I have no addresses to redirect to. Only local files to import.)
I have an index.jx as thus:
<div class="col-md-12">
<div id="create-header"></div>
<div id="create-top-banner"></div>
<div id="create-menu"></div>
<div id="create-focus"></div>
<div id="create-footer"></div>
</div>
I would like to replace the id "create-focus" with new html from another jsx :
import React, { Component } from "react";
import ReactDOM from "react-dom";
import "./AdBanners.css";
class AdBanners extends Component {
render() {
return (
<div className="AdBannerBody" id="ad-banners" ref={this.myRef}>
<h2>Stuff and Things</h2>
</div>
);
}
}
export default AdBanners;
const wrapper = document.getElementById("create-adBanner");
wrapper ? ReactDOM.render(<AdBanners />, wrapper) : false;
I have tried to load just the html, but it simply prints the code to my screen as text. Do I need to run another render call? How is that possible?
I don't understand very good what you're trying to do, is it to set the inner html of the div "create focus"?
take a look at:
https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
You are misusing ReactDOM.render. The second argument should be a reference to a normal HTML element you want to render your element as the child of. So in your case you would want to call:
ReactDOM.render(<AdBanners />, document.getElementById("create-focus"))
Although I'm not sure this is exactly what you're trying to do. The setup for this app seems very strange to me.

Map variables not usable in Scala Play HTML template

I have the following code in one of my Play .scala.html templates:
#formats.map(format => {
<div id="#format">
{format}
</div>
})
formats is a Seq of enumerations. The divs are created, with the proper "format" content (each contains a different format string), however, the ids are never set correctly. The id of each div is literally set to "#format", like this:
<div id="#format">
OneOfTheFormats
</div>
<div id="#format">
AnotherFormat
</div>
I've tried making the code <div id="{format}">, <div id={format}>, and <div id=#format> with no luck. It's odd, because I have done similar things in my other templates, but perhaps it's not working because of the special map case... maybe because format is a created argument, and not passed into the template?
UPDATE:
I tried the following, as someone below suggested:
#{
def createDiv(f: String) = {
<div id="#f">
{f}
</div>
}
formats.map(f => {
createDiv(f.toString)
})
}
Again, The formats are printed correctly inside the div, but the ID is never set. I'm beginning to think this isn't possible. I've also tried <div id="#f">, <div id="{f}">, and <div id="#{f}"> with no luck. Oddly enough, in order to print the format inside the div, I have to use {f}, and not #f. Still struggling here...
UPDATE 2:
It works if I do the following: <div id={f}> ... no quotes! God damn.
As I know, there are some limitations for declaring new variables in new templates, but you can use such a workaround:
#createDiv(format: String) = {
<div id="#format">
#format
</div>
}
And use it in your code like this:
#formats.map(format => {
createDiv(format.toString)
})
This worked for me. Hope this solution suits you.
it seems that there is name collision then you use "format" as a variable name probably because of String.format, try with different name
#formats.map{f =>
<div id="#f">
#f
</div>
}
The following worked for me:
#{
def createDiv(format: String) = {
<div id={format}>
{format}
</div>
}
formats.map(format => {
createDiv(format.toString)
})
}
Note the enclosed #{ } block, and that there are no quotes around the id part of <div id={format}>.
UPDATE:
I ended up doing something a bit cleaner - I used a separate template file. The code looks a bit like this now:
#formats.map(f => {
// do some other stuff
// render format subview
formatSubView(f, otherStuff)
})
And the sub-view template looks like the following:
#(f: theFormatEnum,
otherStuff: lotsOfOtherStuff)
<div id="#f">
<img src="#{routes.Assets.at("images/" + f + ".png")}"/>
// etc, etc
</div>

*Multiple* Print Specific Div

I'll try to explain:
I have numerous div classes, but for the sake of simplicity, let's say I only have 3.
Someone is viewing DIV 1, and I want to give them the option of only printing DIV 1, omitting 2 and 3.
However, on the same page, I would like to give them the option to ONLY PRINT DIV 2. Or only print DIV 3.
I think I get how you can omit certain things from getting printed. But how can you select a section here or there on the same page to be printed with a print link.
Thanks,
Tracy
You can use jQuery to show/hide divs. Read the jQuery tutorial:
http://docs.jquery.com/Tutorials
The code will look this way:
<script>
function showDiv(n) {
$('.divs').hide();
$('#div_'+n).show();
}
$(document).ready(function() { showDiv(1); });
</script>
<a href='javascript:showDiv(n)'>show div n</a>
<div class='divs' id='div_n'>I'm div n</div>
There are many related posts on printing div content, this particular question was still open though it was asked in '10.. Following JavaScript function can be used for printing content of a selected Div tag. Hope this helps. Declaimer: I used some of the existing answers, fixed/enhanced code/error(s) to work with (and tested on) IE-8.
function printDiv(divName) {
var divToPrint = document.getElementById(divName);
var newWin = window.open('', 'PrintWindow', 'width=400, height=400, top=100, left=100', '');
newWin.document.open();
newWin.document.write('<html><body onload="window.print()">' + divToPrint.innerHTML + '</body></html>');
newWin.document.close();
setTimeout(function () { newWin.close(); }, 10);
}
Call printDiv from anywhere in page or from within selected Div. Here is test link:
Print Customer Data
Print Order Data
Assign respective IDs to Div that is to be printed:
<div id="divCustomerData">Div Contents goes here... </div>
The only catch right now is it loses css styles. I'll update response when i get a chance to fix it. Thanks.
https://github.com/jasonday/jquery.printThis
I would give each div an id, and then using the above plugin (i wrote) specify according to div id.