How to integrate a variable in src path for an image? - react-bootstrap

I try to integrate a name from json in a path to an image
I already used this and don't really help because the program "can't resolve" the path:
"./photos/${{row.name}}.jpg"
"./photos/${row.name}.jpg"
"./photos/"+{row.name}+".jpg"
var x = {row.name}
"./photos/${x}.jpg"
{items.map(row =>(
<tr>
<td>
<Link to="/doctor">
<img
src={require("./photos/${{row.name}}.jpg")}
className="d-inline-block align-top"
alt={""}
/>{row.name}
</Link>
</td>
I expect ./photos/nameFromJson.jpg but it can't be resolved

If you want to use variables inside a string, the best way to do that is using template literals.
The template literals should look like this:
`string ${expression} string`
So, the code snippet that you provided, should look like this:
{items.map(row => (
<tr>
<td>
<Link to="/doctor">
<img
src={require(`./photos/${row.name}.jpg`)}
className="d-inline-block align-top"
alt=""
/>
<span>{row.name}</span>
</Link>
</td>
</tr>
))}
If your image names are correct, and everything is inside the photos then it should work like a charm. Basically you have made a few syntax mistake.

Related

Confused with BEM: how to deal with IMG and TABLE tags

I'm trying to wrap my head around BEM naming convention in CSS, but for some parts I find it bit confusing.
In my case, my HTML (on a rough level) looks like this:
<div class="wrapper">
<img src="images/img.png">
<span class="header">Heading</span>
<table>
<tbody>
<tr>
<td class="itemInfo">
<span class="item">Item</span>
<span class="itemDetails">Item Details</span>
</td>
<td class="itemDate">01/01/1980</td>
</tr>
</tbody>
</table>
</div>
In my CSS I have defined styles for the .wrapper, .header, .item, .itemInfo, .itemDetails and .itemDate classes. Turning these into BEM should be straightforward.
However, my questions are related to some other tags in my HTML:
1) How do I deal with the IMG tag? It has styling defined in my CSS file:
img {
style definition 1;
style definition 2;
..
}
Should I BEM this element, both in HTML and in CSS files, by giving image tag a CSS class with BEM convention in my HTML file and also defining this very same class in my CSS, too?
2) In my example, how is TABLE tag understood in the BEM context? In other words, TABLE and TD selectors have their own style definitions in my CSS file (the same way as the IMG tag). Should I also treat those tags the same way as in the case of IMG tag (with/without BEM)?
BEM is designed to provide clarity to developers reading code, especially since CSS/Sass can get convoluted easily. For your <img> tag, I can make one of two assumptions:
You have styling you want to apply to all images, but also
specific styles to apply to this.
There are no other <img> tags and it doesn't matter.
Either way, you should create some CSS classes like so
.standard-img{
rule1: universal-value;
rule2: universal-value;
}
.img-to-style{
rule1: that-only-applies-to-this-img;
}
Obviously, your <img> HTML should look like this, then:
<img class="standard-img img-to-style" src="blah" />
As for the Table, what does it do? I'd do something like this:
<table class="ItemsTable">
<tbody>
<tr class="table__item-row">
<td class="item-row__info">
<span></span>
<span></span>
</td>
<td class="item-row__date">
// Content
</td>
</tr>
</tbody>
</table>
Makes sense, right? Mirror it in your CSS.

Could not parse as assignation expression: "${attrs ?: defaultAttrs}"

What am I missing with the following thymeleaf markup:
<tr th:fragment="row" th:with="defaultAttrs='placeholder=\'' + ${placeholder} + '\''">
<td>
<input th:attr="${attrs ?: defaultAttrs}" />
</td>
...
</tr>
called from
<th:block th:include="row::row(attrs='value=\'*{prodName}\', minLength=\'.{2, 16}\', required, title=\'starts with an alphabet 2 and 8\' placeholder=\'Product name\'')" />
which is producing this error:
Could not parse as assignation sequence: "${attrs ?: defaultAttrs}"
On an unrelated note, had to do a double take at the exception message for the interesting usage of the word assignation instead of assignment
You are trying to pass text string to th:attr. Thymeleaf expects expression, but not string. Next example will NOT work, but this what you're trying to do:
<input th:attr="${'placeholder=\'defaultPlaceholder\''}" />
I suggest you next way:
<tr th:fragment="row" th:with="defaultPlaceholder='placeholder', defaultMaxlength=10">
<td>
<input th:attr="placeholder=${placeholder?:defaultPlaceholder},
maxlength=${maxlength?:defaultMaxlength}" />
</td>
...
</tr>
It looks longer, but gives you more control for manage attributes.
Updated: If you prefer pass all attributes in one string variable, you can use Thymeleaf's preprocessing. For example, next code, is how you going to use fragment in your page:
<div th:include="fragment :: row(attrs='value=\'*{prodName}\', minLength=\'.{2, 16}\',
required=true, title=\'starts with an alphabet 2 and 8\', placeholder=\'Product name\'')">
Then you fragment will something like this:
<div th:fragment="row">
<div th:with="defaults='placeholder=\'placeholder\', maxlength=10'" th:remove="tag">
<tr>
<td>
<input th:if="${attrs!=null}" th:attr="__${attrs}__"/>
<input th:if="${attrs==null}" th:attr="__${defaults}__"/>
</td>
...
</tr>
</div>
</div>
Explanations:
main tag of fragment will NOT be included in result page. So, don't use <tr> as main tag. Instead, wrap <tr> into <div>.
parameters passed to fragment will override all variables declared in th:with of main tag of fragment. So, if you would like to pass any parameters to fragment, don't declare th:with right in main tag of fragment. Do it the body of fragment.
if you don't need to output some tags in result page, just use th:remove attribute. This attribute allows you to remove parts of fragment. In this example we used second <div> just to declare th:with and we don't need this <div> in result page.
You have error in attr paramter of th:include. Because attribute is pair of name and value, you can't specify just required. You have to write: required=true. Another one error: you missed comma between title and placeholder. Correct string should be next:
<th:block th:include="row::row(attrs='value=\'*{prodName}\', minLength=\'.{2, 16}\',
required=true, title=\'starts with an alphabet 2 and 8\', placeholder=\'Product name\'')" />

Fallback (default) image using Angular JS ng-src

I'm trying to set an image source using data returned from a modal. This is inside an ng-repeat loop:
<div id="divNetworkGrid">
<div id="{{network.id}}" ng-repeat="network in networks">
<span>
<table>
<tr>
<td class="imgContainer">
<img ng-src="{{ ('assets/img/networkicons/'+ network.actual + '.png') ||
'assets/img/networkicons/default.png' }}"/>
</td>
</tr>
</table>
</span>
</div>
</div>
As is apparent, I want to populate default.png when the network.actual model property is returned as null. But my code is not picking up the default image, though the first image is coming up fine when available.
I'm sure this is some syntax issue, but cant figure out what's wrong.
I have just found out, that you can use both ng-src and src on an img tag and if ng-src fails (variable used does not exists etc.), it will automatically fallback to src attribute.
What I imagine is happening is the src is returning a 404 even if network.actual is null. For example, first value:
('assets/img/networkicons/'+network.actual+'.png')
is evaluating to a 404 src URL, something like ('assets/img/networkicons/null.png'). So in the OR selection, it's truth-y, but the resource is 404. In that case, you can set the fallback via onError with something like:
<img ng-src="{{('assets/img/networkicons/'+network.actual+'.png')}}" onerror="this.src='assets/img/networkicons/default.png'" />
CodePen to demo use cases - http://codepen.io/jpost-vlocity/pen/zqqerL
angular.module('fallback',[]).directive('fallbackSrc', function () {
return{
link: function postLink(scope, element, attrs) {
element.bind('error', function () {
angular.element(this).attr("src", attrs.fallbackSrc);
});
}
}
});
<img ng-src="{{url}}" fallback-src="default-image.jpg"/>
angular.module('fallback', []).directive('actualSrc', function () {
return{
link: function postLink(scope, element, attrs) {
attrs.$observe('actualSrc', function(newVal, oldVal){
if(newVal != undefined){
var img = new Image();
img.src = attrs.actualSrc;
angular.element(img).bind('load', function () {
element.attr("src", attrs.actualSrc);
});
}
});
}
}
});
<img actual-src="{{url}}" ng-src="default.jpg"/>
link
Interesting way to use ng-src. I haven't tested how that expression would be handled but I would suggest doing it a more stable way:
<img ng-src="{{ networkIcon }}" />
And in your controller:
$scope.networkIcon = network.actual ? 'assets/img/networkicons/' + network.actual + '.png' : 'assets/img/networkicons/default.png';
Edit: Just to clarify, I'm not suggesting the best way to do this is to bind the image source directly to the scope but rather to move the image fallback logic outside of the view. In my applications I often do it in the services that retrieve the data or on the server itself and send an image URL so the client only has to worry about a single property.
Edit to address repeater:
angular.forEach($scope.networks, function(network) {
network.icon = network.actual ? 'assets/img/networkicons/' + network.actual + '.png' : 'assets/img/networkicons/default.png';
});
<tr ng-repeat="network in networks">
<td><img ng-src="{{ network.icon }}" /></td>
</tr>
<div id="divNetworkGrid">
<div id="{{network.id}}" ng-repeat="network in networks">
<span>
<table>
<tr>
<td class="imgContainer">
<img ng-src="{{'assets/img/networkicons/'+(network.actual || 'default' )+'.png'}}"/>
</td>
</tr>
</table>
</span>
</div>
</div>
The inline or will work if the the queried variable is undefined. The above will fix your issue
You can supply the alternative image after OR operator like this:
{{ book.images.url || 'Images/default.gif' }}

Hiding DIV in TPL file based on if an image exists?

<div><div style="margin-left:67px"><table style="border:1px #80A0BB solid;" padding="5px"><tr><td><img src="{$smarty.const.DOC_ROOT}/images/thumbs/{$link.ID}-300x225.png" alt="" /></td></tr></table></div></div>
I'm trying to hide a div based on if an image exists on my server. How would I check to see if an image exists and hide the div if it doesn't exist? Or is there a better way to do this?
The easiest way is just to use write a function in PHP and then use it in Smarty.
In PHP:
function linkImageExists($link){
//Check to see if image for link exists and return true if it does.
// otherwise:
return false;
}
In Smarty template:
{if linkImageExists($link)}
<div>
<div style="margin-left:67px">
<table style="border:1px #80A0BB solid;" padding="5px">
<tr>
<td>
<a href="{$link.URL|trim}" target="_blank">
<img src="{$smarty.const.DOC_ROOT}/images/thumbs/{$link.ID}-300x225.png" alt="" />
</a>
</td>
</tr>
</table>
</div>
</div>
{else}
{* image doesn't exist *}
{/if}
You may want to consider turning $link into an object and then you can call functions on it, rather than having to use global functions which may producer cleaner code in the future.

xpath expression to access tags after script

I have some problem getting all the html tags after script using Xpath
my html :
<table dir = "rtl .......">
<tbody>
<script src = "get.aspx?type=js&file=ajax&rev=3"......>
<script language = "JavaScript"......>
<script>..</script>
<tr>
<td id = "jm0x1"some code here...>
<td id = "jm0x2"some code here...>
also a lot of <tr> here....
</tbody>
how i can access all (td id = "jm0x..)
this is the page i want to parse: http://kooora.com/?c=6423
Something like this should work
//td[contains(#id, "jm0x")]
Then you can affine the contains string to the pattern you want.

Resources