How to prefix values when templating them with rivets? - javascript

I am working with the rivets.js library to template data into my application. I am stuck at a kind of a formatting issue. How do I format values while templating them?
For example I have to template the user's photo location inside the image tag and I am getting the name of the file stored on the server from my DB.
It will be a hashed value but I need to prefix it with /img/uploads/ or something like that and postfix it with maybe .jpeg
I am checking if the value is null or not and this is my code:
<img rv-unless="user.photo" src="img/avatars/sunny-big.png" alt="me" data-toggle="modal" data-target="#myModal">
<img rv-if="user.photo" rv-src="user.photo" alt="me" data-toggle="modal" data-target="#myModal">
<i class="fa fa-camera"></i>
If I do something like rv-src="/img/uploads/user.photo", it wouldn't work for obvious reasons. How to get around this problem?

I think the solution to your problem is using formatters Rivets. They are like filters in AngularJS and support piping.
You can define a formatter as follows:
rivets.formatters.imgPath = function(value){
return '/img/uploads/' + value + '.jpeg'
}
Then you can use it in your markup like:
rv-src="user.photo | imgPath"

Related

Why is my html entity not converting after wrapping it around a template literal?

What I am trying to do
I am trying to make my mailto ahref tag dynamically change the subject tag.
The Problem
I encoded my email to HTML entities (#) (I am using html entities to avoid spam-bots), so whenever I use template literal to wrap around the HTML entities, it doesn't convert anymore.
Example
This is the current working mailto ahref tag that does not have dynamic subject (this one works)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<h3>This is the current working mailto ahref tag that does not have dynamic subject</h3>
<a className="btn btn-primary mx-auto" href="mailto:henryly213#gmail.com?Subject=RandomSubject">
Contact Us
</a>
This is the mailto ahref tag that I attempting to do dynamic subjects
<h3>The Problem I am trying to solve</h3>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<a
className="btn btn-primary mx-auto"
href={`mailto:henryly213#gmail.com?Subject=${email}`}
>
Contact Us
</a>
What I have tried
I thought of putting the html entity in a variable and putting it inside the template literal; however it continue to not work.
//the code doesn't actually look like this but just a quick idea on what I did
const email = "mailto:henryly213#gmail.com"
const subject = "random subject"
<a className="btn btn-primary mx-auto" href={`${email}?Subject=${subject}`}>
Contact Us
</a>
The next thing I tried was concatenate a regular string with a template string but that also didn't work
const randomSubject = "hi";
const email ="mailto:sales#aeris.com.sg";
const subject = `?Subject=${randomSubject}`;
<a className="btn btn-primary mx-auto" href={email + subject}>
I would appreciate any help like changing of the code, links to post that solve this problem , or correction on my lack of knowledge.
React deals with the DOM not with raw HTML.
The JavaScript value you pass gets assigned as the value of the attribute in the DOM.
It is not passed through an HTML parser.
If you want to encode the characters in the string, do so with JavaScript escape sequences instead.

Best practice for using an image inside a selection in a FORM

I'm stuck in a form, I am wondering how can I display an image inside a select option.
Inputs will load text.
What I'm trying to do...
What is the best way to make this work inside the form?
This is what I've done.
So my code is this because <select><option><img href=""></option></select> wont work.
<div class="input-group mb-3">
<input type="text" class="form-control" aria-label="Text input with dropdown button">
<div class="btn-group">
<button type="button" class="no-border btn btn-secondary dropdown-toggle dropdown-toggle-split" id="dropdownMenuReference" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-reference="parent">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu " aria-labelledby="dropdownMenuReference" style="position: absolute;transform: translate3d(-352px, 35px, 0px);min-width: 380px;overflow-x: hidden;" x-placement="bottom-start">
#foreach($categories as $category)
<a class="dropdown-item" href="#"><img class="rounded" src="/storage/category-icon/{{$category->business_icon}}">{{$category->business_name}}</a>
#endforeach
</div>
</div>
</div>
What is the best practice for this?
(using bootstrap 4 and laravel btw)
Since it is not possible to do that with native HTML elements, you cannot make it work without Javascript. Therefore you at least need a hidden input field (<input name="foo-bar-baz" type="hidden value="…" />) to transfer the data between the server and the client. The data could be a simple serialized JSON Object like so:
[
{
"label": "Click ME",
"icon": "/img/icon.png",
"value": "item-xxx"
},
…
]
Going from there you need to write some Javascript code that generates something that looks like a <select> but isn't. Each change on that »virtual field« needs to modify the respective hidden one's value, such that at submission, the correct value is transferred to the server.
Here I could find an example based on bootstrap, maybe that is helpful. It renders a <ul><li></li>…</ul> list to display the »virtual field«.
One possible solution maybe found here.
To sum up, you need to find a proper Javascript library that helps you doing it, or write some code by yourself to make it. Which one to choose strongly depends on your needs and requirements.
Another thing to keep in mind here is accessibility — what should happen if the user has Javascript disabled, or uses a browser that has problems to execute the code provided. Then it might be a good starting point to render a regular <select> and use data attributes to inject images like so:
<select name="foo-bar-baz">
<option value="value" data-icon="/path/to/icon">Label</option>
</select>
which yields a working form element, which then can be enriched with icons, in case Javascript works properly.
So to answer the question: IMHO best practice is the solution which always works and doesn't exclude users without Javascript, a screen reader or a text-based browser. So the solution provided above, starting with a regular <select>, which should be progressively enhanced, is what I would call best practice here.

Reinvoking Vue.js html parsing

I have template with some Vue.js attributes and binding. For example:
<a v-on:click="loadAdditionalBusinesses()"
v-if="!additionalBusinesses"
class="btn btn-info btn-sm btn-block">Load additional profiles</a>
<div v-if="additionalBusinesses" v-html="additionalBusinesses"></div>
After clicking tag i'm downloading from ajax html alone, not json data (because of reasons). This html contains some vue.js attributes like:
<a v-on:click="doSomething()">
Unfortunately, even though "doSomething" method is defined inside proper Vue.js Object and tag is nested in proper node it is not being invoked, because, as i suspect, Vue didnt parsed this html after that ajax call.
Is there any way to 'reparse' such html?
Eventually i managed to succeed the task using this resource: https://github.com/vuejs/vue/issues/679
and v-bind:is attribute and mixing in component.

How can this element button be clicked using protractor?

I'm trying to select this button using protractor:
<button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 0)">
<i class="glyphicon glyphicon-chevron-up">
</i>
</button>
the only unique element in this is ng-click="$arrowAction(-1, 0)"
Nothing I have tried works:
element(by.css("//button[#ng-click='$arrowAction(-1, 0)']")).click();
//button[#ng-click='$arrowAction(-1, 0)'] is not a valid CSS selector. It actually looks like this is an XPath expression and you meant to use by.xpath() locator.
You can though use the partial attribute check instead:
$("button[ng-click*=arrowAction]").click();
$ here is a shortcut to element(by.css(...)), *= means "contains".
Or, do an exact match:
$("button[ng-click='$arrowAction(-1, 0)']").click();
I still don't like the location technique used in this case, but, given what we have, it is probably the best we can do. Ideally, if you have control over the application code and templates, add a meaningful id, class or a custom data attribute to uniquely identify the element.

Angularjs Image Compress passing value into $scope model

I would like to ask, so I came across this angular image compress function which works great as per what I want. I have successfully implement it to work but there is 1 problem, the compress function returns me with a base64 encoded image which is stored in a local $scope and can only be called in the html page itself if I am not mistaken like such.
<td style="width: 15%">
<div class="canvas-wrapper">
<img class="canvas-image" ng-src="<%image1.compressed.dataURL%>"/></div>
</td>
<td>
<input id="inputImage" ngf-select ng-model="statusData.file" ngf-multiple=false type="file" accept="image/*" image="image1" resize-max-height="800" resize-max-width="800" resize-quality="0.5" resize-type="png" />
</td>
In order for me to get the compressed image I have to echo the base64 code by calling <%image1.compressed.dataURL%>
Now my problem is how should I pass this value into the $scope model that i have created specifically to store this value? I tried doing something like
<%$scope.imageCache.data = image1.compressed.dataURL%> but it did not work.
I need the conpressed data to be passed into my custom module so I can perform other actions with the image.
Here is a Demo of the code working code
Hopefully someone can help me in such scenario.
Update 1: Found a temporary cheating workaround is by calling ng-click="image1 = null" when user click on the icon.
ng-src is a directive that evaluates its content. Thus you should provide a value from your $scope.
<img class="canvas-image" ng-src="image1.compressed.dataURL"/>
This will provide the data given that in $scope.image1.compressed.dataURL you have correct data.
So without using ng-src it would be
<img class="canvas-image" src="{{image1.compressed.dataURL}}"/>
Or with your modified interpolation symbols
<img class="canvas-image" src="<%image1.compressed.dataURL%>"/>

Categories