R shiny: How to insert html link in a material_button - html

I would like to open a html link when I click on a button, a "material button" from the shinymaterial package
library(shiny)
library(shinymaterial)
ui <- material_page(
title = "page",
material_button(
input_id = "button1",
label = "label1",
color = "blue"
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
I can do :
label = a("label1",href="my link",target="_blank")
but then it works only when I click on the label of the button.
Can I add my link on the server part of the shinyapp?

You can always use Javascript, but there is another approach if you know all these Shiny UI are just html code.
I answered a similar question before, which is actually a general method that can solve many different questions.
First we look at what is a material button:
> material_button(
+ input_id = "button1",
+ label = "label1",
+ color = "blue"
+ )
<button class="waves-effect waves-light btn shiny-material-button blue" id="button1" value="0">label1</button>
All the Shiny UI functions just generate html code with some attributes, and you can run them in console to see the result, this is a easy way to experiment.
If you look at ?shiny::actionButton, there are actionButton and actionLink. What is the difference?
> shiny::actionButton("test", "button")
<button id="test" type="button" class="btn btn-default action-button">button</button>
> shiny::actionLink("test", "button")
<a id="test" href="#" class="action-button">button</a>
Instead of insert link in a button, we can create a link with appearance of button.
You can play with all the Shiny html tag functions if you know what the html code should look like for your purposes. Now we want a link with some text, a target, some css class.
A dynamic link in Shiny can be created like this:
a(h4("Open Link"), target = "_blank", href = paste0("http://www.somesite/", some_link))
Note this is not the simplest way to create link. I used this format because I want to be able to generate link dynamically in server code. This example can give you some hints on how to combine different html tag functions:
overall it's a link so we use a in outmost layer
you can use any format to show the text/label, I used h4, which probably will be override by the css, but this give you the idea
you can generate the attributes dynamically
Then we just need to apply the proper css class to it to make it look like a material button:
> shiny::a(h4("Open Link", class = "waves-effect waves-light btn shiny-material-button blue" , id = "button1",
+ style = "fontweight:600"), target = "_blank",
+ href = paste0("http://www.somesite/", "some_link"))
<a target="_blank" href="http://www.somesite/some_link">
<h4 class="waves-effect waves-light btn shiny-material-button blue" id="button1" style="fontweight:600">Open Link</h4>
</a>
Note I used full qualified name shiny::a, otherwise sometimes there could be warnings for some short html tag function names. I also added a style attribute which is probably not needed in this case but this is a simple way to make further customizations.
Note:
the color parameter may change the css class value, so you need to use the specific value from that.
action button have an id which can be used for event observer, but for a button of link you usually don't need that because the behavior is just opening a link.
Another hint for customizing Shiny app visual appearance:
run the Shiny app in browser, turn on developer tools in Chrome/firefox
find the css for the element you want to change, experiment with it until you are satisfied with it
save it in a css file under www folder, include it in UI code with includeCSS("www/styles.css").

As it seems it cant be passed as an argument for the materialButton() so instead you could add it yourself via javascript:
Find the element by Id and add an onlick listener.
library(shiny)
library(shinyjs)
library(shinymaterial)
ui <- material_page(
useShinyjs(),
title = "page",
material_button(
input_id = "button1",
label = "label1",
color = "blue"
)
)
server <- function(input, output) {
runjs("document.getElementById('button1').onclick = function() {
window.open('http://stackoverflow.com/', '_blank');
};"
)
}
runApp(shinyApp(ui = ui, server = server), launch.browser = TRUE)

Related

HTML text field input -> site on my page

I have a problem with my HTML-Website.
I would like to have a text field which generates a link after entering and pressing a button from the input. For example, in the text field is "development" and by pressing the button should my browser go to "www.laurensk.at/development".
I donĀ“t have the code for that...
I've understood your question, you can do it using JQuery or Javascript
$("#btnGoto").click(function(){
window.location="www.laurensk.at/"+$("#txtPage").val();
});
I hope this will help you.
You can use the addEventListenerfunction to generate the link when there is a new input in the field.
Example:
var path = document.getElementById("path")
var link = document.getElementById("link")
function makeLink() {
link.href = "http://my.web.site/" + path.value
link.innerHTML = "http://my.web.site/" + path.value
}
path.addEventListener("keyup", makeLink)
<input id="path"/>
<br>
<a id="link" target="_blank"></a>
Documentation: EventTarget.addEventListener() - Web APIs | MDN

Angular Hide With Button

So I'm working with Angular and I'm trying to make a button that when clicked disappears. I have tried to use [hidden], (click)="showHide = !showHide", and a bunch of other methods. Nothing is working so far.
My html (currently):
<div class="rows">
<div class="a-bunch-of-styles-for-my-button">
<a type="button" class="more-styles" (click)="inboundClick = !inboundClick" [routerLink]="['/inbound']" href="">
</a>
</div>
</div>
and my component:
export class AppComponent {
inboundClick = false;
}
In essence I have 2 buttons on a page and when one button is clicked I want to hide both buttons and display a set of new buttons.
I'm very new to Angular and I'm very confused why this won't work.
Your HTML
<div class="yourCssClass" *ngIf="this.isButtonVisible" (click)="this.isButtonVisible = false">
...
</div>
Your TypeScript
export class AppComponent {
private isButtonVisible = true;
}
This should do the job. *ngIf automatically hides the element, if the condition evaluates false, so setting the variable to false is sufficient.
The problem I see here is, that you don't control the visibility at any point. Using [ngClass] to add a specific class, if a condition is met, or *ngIf is helpful, whenever you try to change elements on user interaction.
For more information on [ngClass], you can read about its usage here: https://angular.io/api/common/NgClass
You can read about *ngIf here: https://angular.io/api/common/NgIf
Especially the "Common Use" part should be interesting for you.
Edit:
Reading your comment below it seems you did not notice what [hidden] and (click) actually do. [hidden] controls the visibility of the element, usually dependent on a certain condition. (click) however is a quick way to bind a Click-Event to your element.
Using both of those tools enables to hide an element, by changing a variable, if a user clicks on your element (the new value of the variable may be assigned by a function called by (click) or inline, as demonstrated in the example code).
Edit2: Yep, you meant Angular2/4 ;) So this should do the job.
Here is how you can achieve that:
In your component.html:
<a type="button" class="more-styles"
[hidden]="!inboundClick"
(click)="inboundClick = !inboundClick"
[routerLink]="['/inbound']" href="">
</a>
<a type="button" class="more-styles"
[hidden]="!outboundClick "
(click)="outboundClick = !outboundClick "
[routerLink]="['/outbound']" href="">
</a>
... and in your AppComponent:
export class AppComponent {
inboundClick = true;
outboundClick = true;
}
PLUNKER DEMO
Here is a neat way to hide/remove items, specially handy if there is a list of items.
Note how it takes advantage of Angular's template variables (#ListItem).
So your template can either be something like:
<a type="button" #ButtonA
(click)="onClick(ButtonA)"
[routerLink]="['/inbound']" href="">
</a>
<a type="button" #ButtonB
(click)="onClick(ButtonB)"
[routerLink]="['/outbound']" href="">
</a>
Or like this:
<ng-container *ngFor="let item of list">
<div #ListItem>
<button (click)="onClick(ListItem)">
</div>
</ng-container>
Depending on how you want to hide - if you want to remove it from DOM, or just hide it with CSS. And depending if you want to toggle it or just remove it completely. There are a few options:
Remove element from DOM (no way to get it back):
close(e: HTMLElement) {
e.remove();
}
Hiding it with the hidden attribute - beware that the hidden attribute can be overriden by CSS, it will happen if you are changing the display property and the rule has more precedence:
close(e: HTMLElement) {
e.toggleAttribute('hidden');
}
Hiding it "manually" with CSS:
close(e: HTMLElement) {
e.classList.toggle('hide-element');
}
.hide-element {
display: none;
}

GlassMapper Render Link add Target for external Links

We are on sitecore 8.1 GlassMapper 4.4.1.188.
We are rendering an image in an anchor like below:
using (BeginRenderLink(item, x => x.CarouselLink, isEditable: true))
{
#RenderImage(item, x => x.CarouselImage, isEditable: true)
}
All works well.
How can we force Renderlink to insert Html Target attribute based on sitecore input from General Link?
So, if content editor picks "External link" we need link to be generated with target="_blank"
When you select external link, use New browser option:
This is cshtml code:
#using (Html.Glass().BeginRenderLink(Model, x => x.Link))
{
<span>aaa</span>
}
and this is html output:
<span>aaa</span>

AngularJs - how to support a textbox with hyperlinks

I'm new to Angular but I'm trying to implement a textbox that allows users to enter in links. I only want to support links, and otherwise I want to block all html from being presented as such. I could theoretically use something other than a textarea, but my requirements are that it must be bound to a variable in my scope (right now with ng-model) and I cannot accept html tags other than '< a >'
Here is my example plnkr
In the example, I would like the second seeded item to display as a link, blue and underlined. However, the third item should display as it is currently shown (without interpreting it as html).
HTML:
<textarea maxlength="160" ng-model="val.text"></textarea>
<div class="btn" ng-click="submit()">Submit</div>
<br><br>
<div ng-repeat="item in items">
{{display(item)}}
</div>
JS:
$scope.submit = function() {
if (!$scope.val.text) return
$scope.items.push($scope.val.text);
}
$scope.display = function(txt) {
return txt;
// something here? if txt contains <a> and </a> indicate
// that we should display as html
}

Trying to put Bootstrap modal in a button

Is there a way I can use a button(input type="button") to show the Bootstrap modal. Basically the default is using anchor based on the documentation. I have tried experimenting but no luck.
I'm not sure if my coding is wrong or the Bootstrap modal can only be activated if it is an anchor tag. I have also tried googling or researching if anyone has created this kind of result.
This should work the same way as with an anchor tag.
The problem is, it's based on the href attribute, referring to the id of the modal window, and placing this attribute on a button might cause some html validation to go wonky.
If you don't care about that kind of stuff you can just replace your a tag with a button tag.
Edit: just noticed you were using an input element rather than a button. Either way, it should still work.
Edit2: Just verified if what I was saying wasn't total BS by looking at the bootstrap code (2.3.2), and found this snippet:
$(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
var $this = $(this)
, href = $this.attr('href')
, $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
, option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
e.preventDefault()
$target
.modal(option)
.one('hide', function () {
$this.focus()
})
})
Looking at this, the href attribute isn't required, and you can use data-target instead when working with inputs and buttons.
simply u can fire event on Button Click and call function "onclick=showModal()"
JS CODE
function showModal()
{
$("#modal-window-id").modal("show");
}