Set attribute as variable in reactstrap - reactjs

In reactstrap, I saw some single word attributes, like active, flush.
How to make them a variable to dynamic bind with dom?
<ListGroup>
<ListGroupItem active>
<ListGroupItemHeading>List group item heading</ListGroupItemHeading>
<ListGroupItemText>
Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.
</ListGroupItemText>
</ListGroupItem>
</ListGroup>

The single word attributes in JSX actually represent:
<ListGroupItem active={true}></ListGroupItem>
The true value is implicit when represented with just the keyword.
To convert that to a variable:
<ListGroupItem active={this.state.active}>
<ListGroupItemHeading>List group item heading</ListGroupItemHeading>
<ListGroupItemText>
Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.
</ListGroupItemText>
</ListGroupItem>
Now, the change to state.active will also reflect the attribute value for active

Related

How to use the Trans component for bold or italicized text in the middle of a translation

This has been asked before, but I'm not able to comment on existing posts due to lacking reputation points so I am creating my own question.
I have a hard time understanding how to use the Trans component properly, as I find its documentation page to be a bit lacking and unclear.
I am trying to use nested bold or italicized text in my JSON strings. For context, I have translation file called "homepage.json" which I am keeping in my React app's public/locales/en/ subdirectory, using a format as follows:
{
"main": {
"paragraph-text": "Lorem ipsum dolor sit, <1>amet consectetur adipisicing elit</1>. Dolore ab modi autem veniam aperiam mollitia at assumenda sint repellat sunt quia recusandae laboriosam tempora, aliquam nemo in nostrum laudantium? Temporibus."
}
}
My Trans component looks like this:
<Trans i18nKey={"homepage.main.paragraph-text"}>
Lorem ipsum dolor sit, <em>amet consectetur adipisicing elit</em>. Dolore ab modi autem veniam aperiam mollitia at assumenda sint repellat sunt quia recusandae laboriosam tempora, aliquam nemo in nostrum laudantium? Temporibus.
</Trans>
When I try to create a French translation file for homepage.json, under public/locales/fr/ while using the exact same format as its English counterpart, when toggling between languages the library is not making use of the French text.
This answer seems to describe exactly what I want to achieve, and I have attempted to implement the outlined solution into my application, but my Trans component instance does not appear to be able to locate the i18nkey value I pass to it.
Solved the issue. The problem is that I wasn't passing in the namespace of my translation file correctly to the Trans component.
As per my example above, the correct way to use Trans would be:
const { t } = useTranslation('myNamespace')
<Trans t={t} i18nKey={"main.paragraph-text"}>
Lorem ipsum dolor sit, <em>amet consectetur adipisicing elit</em>. Dolore ab modi autem veniam aperiam mollitia at assumenda sint repellat sunt quia recusandae laboriosam tempora, aliquam nemo in nostrum laudantium? Temporibus.
</Trans>
Along with the correct usage in the JSON file:
{
"main": {
"paragraph-text": "Lorem ipsum dolor sit, <0>amet consectetur adipisicing elit</0>. Dolore ab modi autem veniam aperiam mollitia at assumenda sint repellat sunt quia recusandae laboriosam tempora, aliquam nemo in nostrum laudantium? Temporibus."
}
}

ReactJS copy text file content into component on build

I am writing a "Terms of Service" page using ReactJS and my idea is to copy the contents of the file tos-text.txt in the component at build time, to avoid fetching time when the page is opened.
I tried as follows, but with poor results:
<h2>Terms of Service</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas in scelerisque odio, sed
consequat ante. Donec lectus tortor, ullamcorper quis risus nec, cursus hendrerit libero. In hac
habitasse platea dictumst. Quisque et posuere urna. Suspendisse convallis faucibus nulla, non
egestas libero aliquet non. Donec tincidunt purus sed sem suscipit feugiat. Pellentesque rutrum
blandit gravida. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos. Pellentesque erat urna, lobortis sed turpis a, aliquet aliquet lorem. Class
aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla quis
nibh et mi ullamcorper mattis eu eget lectus.
</p>
import { Container } from 'react-bootstrap'
// Page content
import TosText from 'config/tos-text.txt'
// --- Terms of Service ---
const Tos = () => {
return (
<Container className="flex-grow-1 tos">
<div dangerouslySetInnerHTML={{ __html: TosText }} />
</Container>
)
}
export default Tos
Currently the page only shows the link to the generated txt file (/static/media/tos-text.dc220bee.txt).
EDIT:
As #jsejcksn suggested (source-assets), I've tried to install react-app-rewired, using this config-overrides.js:
module.exports = function override(config, _env) {
let rules = config.module.rules[1].oneOf
rules.splice(rules.length - 1, 0, {
test: /\.txt/,
type: 'asset/source',
})
return config
}
But when I try to start the test server, it says:
$ react-app-rewired start
Failed to compile.
Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.module.rules[1].oneOf[8].type should be one of these:
"javascript/auto" | "javascript/dynamic" | "javascript/esm" | "json" | "webassembly/experimental"
-> Module type to use for the module
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Thanks to the suggestion given to me by #jsejcksn I succeeded in my intent.
I will add the solution for anyone who needs it:
1. Install dependencies
$ yarn add react-app-rewired raw-loader
2. Create config ovverride
config-overrides.js:
module.exports = function override(config, _env) {
let rules = config.module.rules[1].oneOf
rules.splice(rules.length - 1, 0, {
test: /\.txt$/i,
use: 'raw-loader',
})
return config
}
3. Include the txt into the component
// Page text
import PageText from 'content/page.txt'
const Component = () => {
return (
<div className="text">
<div dangerouslySetInnerHTML={{ __html: PageText }} />
</div>
)
}
export default Component
(P.S. I bet there's a loader that converts the file to a ReactComponent like for SVG files, but I didn't go any further than that)
You can simply use "embedding" to display your static file within a React component.
Using <embed>:
const Tos = () => {
return (
<Container className="flex-grow-1 tos">
<h2>Terms of Service</h2>
<embed type="text/html" src={TosText} />
</Container>
)
}
Note that with this approach you can't use any markup in your imported text file -- it will not render as markup, but simply as text, that's why the title is outside the <embed> in the example above.
This should render something like:
The content will be scrollable if it doesn't fit in the default <embed> box -- but you can control its size with styles or width and height attributes.
Using <iframe>:
Move your static document to the public folder of your app, and change the extension to .html, and then link to it simply:
const Tos = () => {
return (
<Container className="flex-grow-1 tos">
<iframe title="Terms of Service" src="./tos-text.html" />
</Container>
)
}
And this should look like this:
Again, this is just default look, you can change it with styling.
You can also use <embed> with the second approach (file in the public folder):
<embed type="text/html" src="./tos-text.html" />
You can see a live example on codesandbox.

Toggle div to expand semantic ui card component

I'm using the <Card> component from Semantic-UI-React. I have a group of cards displaying some random information. I have the extra prop defined which renders a button. My idea is to have this button, when clicked, toggle/expand a div to display more information. I have looked around and not been able to find much on how to achieve this.
I looked into <Accordion> from semantic ui as well, but have not been able to get it to play nicely nested inside the card component.
I created a sandbox to show what I have so far and the general look of what I explained above.
For brevity I will only post the code of one card out of the group below.
<Card color="blue">
<Card.Content header="Elliot" textAlign="center" />
<Card.Content description="'Elliot is a sound engineer living in Nashville who enjoys playing guitar and hanging with his cat.'" />
<Card.Content extra>
<Button basic circular icon size="tiny">
<Icon name="plus circle" />
</Button>
Show More
</Card.Content>
</Card>
I agree with #brandon-r that you can handle the extra content being show by handling a state object (in my case an array). What I did differently from his example was to take advantage of the <Card.Content extra> component, which handles all the styles issues.
To handle opening and closing the extra content, I used a simple reducer. I like to use the useReducer hook on those UI interactions that need a more complex state handling. Then I created three components: one that shows the extra content when opened, another that shows the button to display the content, and a third one that toggles between the two. I did it this way to be able to generalise it in the future.
Anyways, here is the link to my forked CodeSandbox with my take on the solution:
https://codesandbox.io/embed/semantic-ui-card-extra-content-toggle-kybt2
I hope it helps
Edit #1
Added style={{height: "100%"}} to the card so they mantain their size when one of the cards is opened.
Edit #2
Add picture showing a card with a long description.
<Card color="blue" style={{ height: "100%" }}>
<Card.Content header="Elliot" textAlign="center" />
<Card.Content description="'Elliot is a sound engineer living in Nashville who enjoys playing guitar and hanging with his cat.'" />
<ExtraContentAccordion
content="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ac commodo diam, et tincidunt massa. Sed aliquet tortor purus, in pulvinar enim mattis ac. Maecenas vestibulum cursus lorem, quis fermentum enim lacinia a. Ut nec feugiat nisl. Morbi finibus hendrerit diam, id iaculis nibh feugiat sed. Sed non justo turpis. Fusce neque quam, facilisis eu aliquam vitae, hendrerit nec nulla. Integer metus sapien, dictum eget viverra et, dictum in lectus. Integer vitae dolor ut libero dictum tristique eget non nunc. Suspendisse diam urna, pretium sed elementum sed, fermentum eu leo. Donec augue tortor, rhoncus id pulvinar ac, fringilla eu est. Duis et ante tristique dui molestie maximus at ut enim. Curabitur facilisis tempor lorem quis scelerisque. Maecenas enim leo, mollis at egestas in, vulputate eget risus."
onToggle={toggleCard(1)}
open={state[1]}
/>
</Card>
If you want to expand to show more content, you can keep track of which cards are expanded with some react state. In the UI, you can use the state to determine if you should render the extra content for a particular card.
EX:
import React, { useState } from "react";
import ReactDOM from "react-dom";
import { Card, Button, Icon } from "semantic-ui-react";
import "./styles.css";
function App() {
const [expanded, setExpanded] = useState({});
const cards = [1, 2, 3, 4, 5, 6];
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Card.Group itemsPerRow={3}>
{cards.map(cardNumber => (
<Card color="blue">
<Card.Content header="Elliot" textAlign="center" />
<Card.Content description="'Elliot is a sound engineer living in Nashville who enjoys playing guitar and hanging with his cat.'" />
<Card.Content extra>
<Button
basic
circular
icon
size="tiny"
onClick={() =>
setExpanded({
...expanded,
[cardNumber]: !expanded[cardNumber]
})
}
>
<Icon name="plus circle" />
</Button>
{expanded[cardNumber] && (
<div style={{ height: 200 }}>
Extra content expanded for card {cardNumber}
</div>
)}
Show More
</Card.Content>
</Card>
))}
</Card.Group>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Here is a short sandbox to see what it looks like: https://codesandbox.io/s/modest-mayer-t12ot

Angular: How to create custom links around text strings using a filter

I am working with a json feed about cars. Part of the text has [VIN:'vin_number_is_here']Car make model here[/VIN]. I am using this in an ng-repeat and would like to, unless there's a better way, use a filter to process the text and create a hyperlink to a custom function ending up with something like <a ng-click="modalViewCar('vin_number_is_here')">Car make model here</a>
I have the replacement of the [/VIN] done but am at a loss for how best to handle the opening "tag".**
Additionally when I have hardcoded a test string I have found that the link never works which I assume is something Angular is responsible for...
app.filter('linkToVIN', ['$sce', function($sce) {
return function(input) {
input = input.replace("[/VIN]","</a>");
**input = input.replace("[VIN='12345abcdef']","<a ng-click=\"modalViewCar('12345abcdef')\">");**
return $sce.trustAsHtml(input);
};
}]);
<div ng-repeat="car in cars">
<div class="col-sm-12" ng-bind-html="car.details | filter:search | linkToVIN"></div>
</div>
The VIN link is in the body of text. Sometimes multiple times. So each ng-repeat has a {{car.details}} which may, about 1 in 3 times, have at least one string with the [VIN] structure. What I'd really like to do is hot link those as they appear within the text as so far I have found a few outlier cases where there are references to other [VIN] numbers. E.g.
Lorem ipsum dolor sit amet, [VIN:'12345abcdef']consectetur[/VIN] adipiscing elit. Vivamus laoreet odio nisi, eget gravida nunc porta gravida. Pellentesque nec porta tortor. In neque mi,[VIN:'000hijk']pretium[/VIN] at mattis ut, consectetur eget felis. Etiam tortor lacus, varius quis augue sed, condimentum varius massa.
Which I would like to convert to.
Lorem ipsum dolor sit amet, < a ng-click="modalViewCar('12345abcdef')" >consectetur< /a > adipiscing elit. Vivamus laoreet odio nisi, eget gravida nunc porta gravida. Pellentesque nec porta tortor. In neque mi,< a ng-click="modalViewCar('000hijk')" >pretium< /a > at mattis ut, consectetur eget felis. Etiam tortor lacus, varius quis augue sed, condimentum varius massa.
solving the regexp
You can do this with one regexp using multiple matching groups to build your anchor tags:
data.replace(/\[VIN:'([\w\d-_]*)'\](.*?)\[\/VIN\]/gmi, '<a ng-click="vc.modalClick($1)">$2</a>')
test - https://regex101.com/r/tU5sG2/2
compiling the DOM
The next issue is that you need to compile the DOM correctly. In order to do that, I recommend a directive
.directive('vinContainer', function($parse, $compile){
restrict: 'A',
link: function($scope, elem, attrs){
regex = /\[VIN:'([\w\d-_]*)'\](.*?)\[\/VIN\]/gmi
anchor = '$2'
data = $parse(attrs.ngModel)($scope)
parsed = data.replace(regex, anchor)
elem.html(parsed).show()
$compile(elem.contents())($scope)
}
}
usage
<div vin-container ng-model="vc.viewData"/>
codepen - http://codepen.io/jusopi/pen/VeebEO?editors=101
This solution assumes that you are tightly coupling your directive to your view controller because your compiled anchors know which method to call. You could further break this down by:
creating an isolate scope with a callback expression you declare on the DOM
have the compiled links call the callback expression passing back the id as the payload
Doing it that way would be much more scalable. Here is the codepen for that version as well - http://codepen.io/jusopi/pen/yeeXJj?editors=101
Say your cars array looks something like this
var cars = [{details: "[VIN='12345abcdef']something[/VIN]"}, {details: ...}, ...];
You can transform it to a usable object by mapping the array
$scope.cars = cars.map(function(car) {
var parts = car.details.match(/^\[VIN='(.+?)'\](.+?)\[\/VIN\]$/);
return {
vin: parts[1],
details: parts[2]
};
});
and then in your template
<div ng-repeat="car in cars">
<a ng-click="modalViewCar(car.vin)" ng-bind-html="car.details"></a>
</div>
This makes the assumption that all your car.details entries match the regular expression.

Codeigniter ActiveRecord not returning any results for particular tableUn

Having a problem with returning results from one particular table in a database.
I have two tables:
a) repository_notes
b) repository_noteupdates (this one is giving the problem)
Here is an image showing there are some data in both tables using a simple select * query using Navicat.
http://imgur.com/GA6bn
However When I query repository_notes below:
print_r($this->db->get('repository_notes')->result_array());
It gives me the following result set:
Array
(
[0] => Array
(
[note_id] => 1
[note_title] => This is my note
[note_content] => Lorem ipsum dolor sit amet, consectetur adipiscing elit. In laoreet lobortis lacus, ac iaculis risus tristique nec. Curabitur porta gravida est, non tincidunt nunc porta nec. Nunc diam metus, feugiat non lobortis
[note_userId] => 2302
[note_pageno] => 12
[note_deleted] => 0
[note_bookid] => 12
)
[1] => Array
(
[note_id] => 2
[note_title] => This is my note
[note_content] => Lorem ipsum dolor sit amet, consectetur adipiscing elit. In laoreet lobortis lacus, ac iaculis risus tristique nec. Curabitur porta gravida est, non tincidunt nunc porta nec. Nunc diam metus, feugiat non lobortis
[note_userId] => 2302
[note_pageno] => 12
[note_deleted] => 0
[note_bookid] => 12
)
However when I run the query below:
print_r($this->db->get('repository_noteupdates')->result_array());
I get no results:
Array
(
)
Have any of you seen anything like this before and have a solution it would be appreciated.
So I found the solution for this.
It seems that if i remove the name update from the table name, it seems to work. So i have called the table repository_noteupdata instead of repository_noteupdates
and it is now working.
Thanks guys for helping out. It is strange because I cannot find any documentation in codeigniter saying update is a reserved word for a table name.

Resources