Semantic.ui dropdown not working with React.js - meteor

I'm trying to use Semantic.ui's dropdown in my Meteor.js + React.js app. Everything else with Semantic.ui works fine, but I can't make the dropdown menu work. Here's my code:
NavigationMain = React.createClass({
componentDidMount() {
$('.ui.dropdown.right').dropdown();
},
componentDidUpdate() {
$('.ui.dropdown.right').dropdown('refresh');
},
_openChat(){
console.log("click");
},
render(){
return (
<div className="ui top attached menu">
<div className="ui dropdown icon item" onClick={this._openChat}>
<i className="comments outline icon"></i>
</div>
<div className="ui dropdown right icon item">
<i className="wrench icon"></i>
<div className="menu">
<div className="item">
<i className="dropdown icon"></i>
<span className="text">New</span>
<div className="menu">
<div className="item">Document</div>
<div className="item">Image</div>
</div>
</div>
<div className="item">
Open...
</div>
<div className="item">
Save...
</div>
<div className="item">Edit Permissions</div>
<div className="divider"></div>
<div className="header">
Export
</div>
<div className="item">
Share...
</div>
</div>
</div>
</div>
);
}
});
I have also tried using Reacts ref attribute to reference the element like this:
$(this.refs.menu).dropdown();
But it doesn't seem to help either.
All the examples I've found, for example the Semantic.ui's official integration doc (http://semantic-ui.com/introduction/integrations.html), work like this and I've made it work before without React. That's why I'm starting to feel helpless.
Any help with this would be appreciated.

Works for me.
var Content = React.createClass({
componentDidMount: function() {
$('.ui.dropdown').dropdown()
},
render: function () {
return <div className="ui dropdown">
<div className="text">File</div>
<i className="dropdown icon" />
<div className="menu">
<div className="item">New</div>
<div className="item">
<span className="description">ctrl + o</span>
Open...
</div>
<div className="item">
<span className="description">ctrl + s</span>
Save as...
</div>
<div className="item">
<span className="description">ctrl + r</span>
Rename
</div>
<div className="item">Make a copy</div>
<div className="item">
<i className="folder icon" />
Move to folder
</div>
<div className="item">
<i className="trash icon" />
Move to trash
</div>
<div className="divider"></div>
<div className="item">Download As...</div>
<div className="item">
<i className="dropdown icon" />
Publish To Web
<div className="menu">
<div className="item">Google Docs</div>
<div className="item">Google Drive</div>
<div className="item">Dropbox</div>
<div className="item">Adobe Creative Cloud</div>
<div className="item">Private FTP</div>
<div className="item">Another Service...</div>
</div>
</div>
<div className="item">E-mail Collaborators</div>
</div>
</div>
}
});
ReactDOM.render(
<Content />,
document.getElementById('container')
);
Here is a fiddle
https://jsfiddle.net/85z7o3n2/

Related

VueJS3 : radio v-model doesn't update when switch changed

I want my input radio that is default checked to update the value in the v-model. But when I switch plan the v-model doesn't update dynamically. I'm stuck. Maybe I have to take a look at "watch" or "ref".
My formValues is reactive and returns the good answer in the v-model. But when I switch plan... doesn't update the check output.
<template>
<!-- Second step -->
<section id="second-step">
<div class="row mt-4 px-2">
<div class="col-12">
<h1 class="h2 fw-bold">Select your plan</h1>
<p class="pt-1">
You have the option of monthly or yearly billing.
</p>
</div>
</div>
<!-- Form 2 -->
<form class="row justify-content-xl-between px-3 pe-xl-0" id="form-plan">
<!-- Plan 1 -->
<div class="col-12 col-xl plan mt-3 p-0">
<label for="arcade-plan" class="plan-label"></label>
<input v-model="check" type="radio" v-if="formValues.billing.monthly" :value="formValues.plan[0].name" name="plan" id="arcade-plan" checked>
<input v-model="check" type="radio" v-else="formValues.billing.yearly" :value="formValues.plan[1].name" name="plan" id="arcade-plan" checked>
<div class="plan-content card ps-2">
<div class="plan-icon mt-1">
<img src="assets/images/icon-arcade.svg" alt="">
</div>
<div class="plan-description">
<span class="plan-title mb-0">Arcade</span>
<div class="price monthly">
<div class="amount mb-0 fs-6 fw-medium text-cool-gray">$9/mo</div>
</div>
<div class="price yearly d-none">
<div class="amount fs-6 fw-medium text-cool-gray">$90/yr</div>
<div class="billing-msg text-primary">2 months free</div>
</div>
</div>
</div>
</div>
<!-- Plan 2 -->
<div class="col-12 col-xl plan mt-3 p-0">
<label for="advanced-plan" class="plan-label"></label>
<input v-model="check" type="radio" v-if="formValues.billing.monthly" :value="formValues.plan[2].name" name="plan" id="advanced-plan">
<input v-model="check" type="radio" v-else="formValues.billing.yearly" :value="formValues.plan[3].name" name="plan" id="advanced-plan">
<div class="plan-content card ps-2">
<div class="plan-icon mt-1">
<img src="assets/images/icon-advanced.svg" alt="">
</div>
<div class="plan-description">
<span class="plan-title mb-0">Advanced</span>
<div class="price monthly">
<div class="amount mb-0 fs-6 fw-medium text-cool-gray">$12/mo</div>
</div>
<div class="price yearly d-none">
<div class="amount fs-6 fw-medium text-cool-gray">$120/yr</div>
<div class="billing-msg text-primary">2 months free</div>
</div>
</div>
</div>
</div>
<!-- Plan 3 -->
<div class="col-12 col-xl plan mt-3 p-0">
<label for="pro-plan" class="plan-label"></label>
<input v-model="check" type="radio" v-if="formValues.billing.monthly" :value="formValues.plan[4].name" name="plan" id="pro-plan">
<input v-model="check" type="radio" v-else="formValues.billing.yearly" :value="formValues.plan[5].name" name="plan" id="pro-plan">
<div class="plan-content card ps-2">
<div class="plan-icon mt-1">
<img src="assets/images/icon-pro.svg" alt="">
</div>
<div class="plan-description">
<span class="plan-title mb-0">Pro</span>
<div class="price monthly">
<div class="amount mb-0 fs-6 fw-medium text-cool-gray">$15/mo</div>
</div>
<div class="price yearly d-none">
<div class="amount fs-6 fw-medium text-cool-gray">$150/yr</div>
<div class="billing-msg text-primary">2 months free</div>
</div>
</div>
</div>
</div>
<!-- Switch billing -->
<div class="col-12 py-3 rounded">
<div class="row bg-alabaster justify-content-center px-2">
<div class="col-10 col-sm-8 col-md-6">
<div class="switch-wrapper py-2 mb-0">
<input id="monthly" type="radio" name="switch" checked>
<input id="yearly" type="radio" name="switch">
<label id="billing-monthly" for="monthly" class="mx-sm-5">Monthly</label>
<label id="billing-yearly" for="yearly" class="mx-sm-5">Yearly</label>
<span class="toggler"></span>
</div>
</div>
</div>
</div>
</form>
</section>
<div class="container">
Selected :
{{ check }}
</div>
</template>
<script>
import { onMounted } from 'vue';
export default {
data() {
return {
check: 'Arcade (Monthly)'
}
},
props: {
step: Number,
formValues: Object
},
setup(props) {
onMounted(() => {
const switchInputs = document.querySelectorAll(".switch-wrapper input");
const prices = document.querySelectorAll(".price");
const toggleClass = "d-none";
/* Switch */
for (const switchInput of switchInputs) {
switchInput.addEventListener("input", function () {
for (const price of prices) {
price.classList.add(toggleClass);
}
const activePrices = document.querySelectorAll(
`.price.${switchInput.id}`
);
for (const activePrice of activePrices) {
activePrice.classList.remove(toggleClass);
}
/* Change billing type */
props.formValues.updateBilling()
console.log(props.formValues.billing.yearly)
})
}
})
}
}
</script>
I didn't find any sources about this problem yet. I think I can do something with a watch or ref.
I think that you're overcomplicating things.
Computed properties are used when you need to combine multiple reactive properties. In this case it would be the message output on selected plan + period.
Here is a working example in CodeSandbox.
Also, you are not using conditional rendering properly, which may be why your data isn't updating correctly.
v-if="logical expression"
v-else-if="logical expression"
v-else
References:
Computed properties
Conditional rendering
Here is a very basic sample of Radio input binding with Vue:
const { createApp } = Vue;
const App = {
data() {
return {
check: 'Arcade (Monthly)',
items: ['Arcade (Monthly)', 'Advanced (Monthly)']
}
}
}
const app = createApp(App)
app.mount('#app')
<div id="app">
<div>Picked: {{ check }}</div><br />
<div v-for="(item, index) in items">
<input type="radio" :id="`item_${index}`" :value="item" v-model="check" />
<label :for="`item_${index}`">{{item}}</label>
</div>
</div>
<script src="https://unpkg.com/vue#3/dist/vue.global.prod.js"></script>

How to show another element with hover in Angular?

This is my demo.
When we hover #image-bg, I want #bg-box-hidden will be display: block.
But I'm losing my way to figure out how to solve the problem
<div class="grid pb1rem">
<div *ngIf="avatar !== null" class="image-content">
<img
class="image-bg"
[src]="avatar"
(click)="selectImage.click()"
hover-class="test"
(mouseover)="onImgMouseover($event)"
(mouseout)="onImgMouseout($event)"
/>
<div #show class="bg-box-hidden" hover-class="show">
<button class="btn only-icon">
<i nz-icon nzType="delete" nzTheme="outline"></i>
</button>
</div>
</div>
</div>
The main problem of your code are
Wrong event name.
The element doesn't rendered so you can't targeted the element.
Here is simple solution for you, It might be other way to implement as well.
Try this one, put on your .ts file of the component.
onImgMouseover($event): void {
const box = document.getElementsByClassName('bg-box-hidden')[0];
box.style.display = 'block';
}
onImgMouseout($event): void {
const box = document.getElementsByClassName('bg-box-hidden')[0];
box.style.display = 'none';
}
and need modify some on HTML something like
<div
class="grid pb1rem"
(mouseenter)="onImgMouseover($event)"
(mouseleave)="onImgMouseout($event)"
>
<div *ngIf="avatar === null" class="image_wrapper">
<input
type="file"
accept=".png,.jpg"
(change)="updateImage($event)"
class="file-input"
#selectImage
/>
</div>
<div *ngIf="avatar !== null" class="image-content">
<img
class="image-bg"
[src]="avatar"
(click)="selectImage.click()"
hover-class="test"
/>
</div>
<div #show class="bg-box-hidden" hover-class="show">
<button class="btn only-icon">
<i nz-icon nzType="delete" nzTheme="outline"></i>
</button>
<div class="box-button-up">
<input
type="file"
accept=".png,.jpg"
(change)="updateImage($event)"
class="file-input"
#selectImage
/>
</div>
</div>
</div>

how to copy color in clipboard , reactjs

I am beginner in reactjs, I want to copy a color when I click on color.
How should it be done?
import React from 'react';
const Green = ()=>{
return (
<div>
<h1 className='g-color-title'>Green Color</h1>
<div className='container-fluid'>
<div className='div-style' id='color31'> #2ECC72 </div>
<div className='div-style' id='color32'> #26AE60 </div>
<div className='div-style' id='color33'> #6AB04A </div>
<div className='div-style' id='color34'> #43BE31 </div>
<div className='div-style' id='color35'> #10A881 </div>
<div className='div-style' id='color36'> #019031 </div>
<div className='div-style' id='color37'> #75DA8B </div>
<div className='div-style' id='color38'> #218F76 </div>
<div className='div-style' id='color39'> #218F76 </div>
<div className='div-style' id='color40'> #7CEC9F </div>
</div>
</div>
)
}
export default Green;
You can use navigator.clipboard.writeText() to copy text to the clipboard.
I would recommend using an object of colors, then with Object.entries() and map() create the <div>s and add an onClick() to trigger it:
const Green = () => {
const colors = {
color31: '#2ECC72',
color32: '#26AE60',
color33: '#6AB04A',
color34: '#43BE31',
color35: '#10A881',
color36: '#019031',
color37: '#75DA8B',
color38: '#218F76',
color39: '#218F76',
color40: '#7CEC9F',
};
return (
<div>
<h1 className='g-color-title'>Green Color</h1>
<div className='container-fluid'>
{Object.entries(colors).map(([id, color]) =>
<div className='div-style' id={id} onClick={navigator.clipboard.writeText(color)}>{color}</div>
)}
</div>
</div>
);
}
export default Green;

Bulma's navbar-buger doesnt connect to menu items in Vue.js 2

I am trying to implement a navbar for my application whose front end is built using Vue 2.0 and Bulma . It works well on desktops and but on smaller screens its showing the burger icon but it is not showing any elements. Its just present.
<template>
<div class="container is-fluid">
<div>
<nav class="navbar is-dark">
<div class="navbar-brand">
<a class="navbar-item" href="#">
<img alt="K R O N O S" height="100px">
</a>
<div class="button navbar-burger" data-target="navMenu">
<span></span>
<span></span>
<span></span>
</div>
</div>
<div class="navbar-menu" id="navMenu">
<div class="navbar-end">
<div class="navbar-item">
<a class="" href="#"> Docs </a>
</div>
<div class="navbar-item ">
<a class="" href="#"> Report </a>
</div>
<div class="navbar-item">
<a class="">More</a>
</div>
<div class="navbar-item">
<a class="">Logout</a>
</div>
</div>
</div>
</nav>
</div>
</div>
</template>
<script>
document.addEventListener('DOMContentLoaded', function () {
// Get all "navbar-burger" elements
var $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0)
// Check if there are any navbar burgers
if ($navbarBurgers.length > 0) {
// Add a click event on each of them
$navbarBurgers.forEach(function ($el) {
$el.addEventListener('click', function () {
// Get the target from the "data-target" attribute
var target = $el.dataset.target
var $target = document.getElementById(target)
// Toggle the class on both the "navbar-burger" and the "navbar-menu"
$el.classList.toggle('is-active')
$target.classList.toggle('is-active')
})
})
}
})
export default {
name: 'Navbar',
data () {
return {
msg: ''
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
div{
border: 0px solid black;
}
</style>
As you can see I have tried implementing the example code in on which was present here but with no use. Shouldnt Bulma give me responsive navbar out of the box. All the examples and solutions I have found are for the older "nav" class not the newer "navbar". Help would be much appreciated.
So, after a bit of studying the Vue guide and clues from fatman's comments, this is the fix I applied.
The above code works , but this is a more vue-ish way to do the navbar-burger menu.
<template>
<nav class="navbar">
<div class="container">
<div class="navbar-brand is-large">
<a class="navbar-item" href="#">
<img alt="K R O N O S" height="100px">
</a>
<button #click="makeBurger" class="button navbar-burger" data-target="navMenu" v-bind:class="{ 'is-active': activator }">
<span></span>
<span></span>
<span></span>
</button>
</div>
<div class="navbar-menu" id="navMenu" v-bind:class="{ 'is-active': activator }">
<div class="navbar-end">
<div class="navbar-item">
<a class="" href="#"> Docs </a>
</div>
<div class="navbar-item ">
<a class="" href="#"> Report </a>
</div>
<div class="navbar-item">
<a class="">More</a>
</div>
<div class="navbar-item">
<a class="">Logout</a>
</div>
</div>
</div>
</div>
</nav>
</template>
<script>
export default {
name: 'Navbar',
data () {
return {
msg: '',
activator: false
}
},
methods: {
makeBurger () {
this.activator = !this.activator
return this.activator
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
div{
border: 0px solid black;
}
</style>
Hope this helps someone. The show/hide functionality is taken care by Bulma.
This works, but
will not close the menu
will cause router-links not to work
For 1.) I recommend adding #click to navbar-item as well:
<a #click="makeBurger" class="navbar-item">
<router-link to="/login">
{{link1}}
</router-link>
</a>

Use watir web driver to click download icon

I am trying to use watir to download files from a web page. Trying to figure out how to click the 'download icon' and then save the file.
The files are in a table, and I want to download each file with the word 'done' in the column and then same it as the report name.
The HTML is below:
<div class="portlet" id="homeStatus">
<div class="portletHeader statusHeader">
Reports and Request Status
</div>
<div class="portletContent" id="statusContent">
<div class="status">
<div class="row-fluid boldText statusHeaderRow">
<div class="span3">Name</div>
<div class="span2">ID</div>
<div class="span3">Date</div>
<div class="span1">Status</div>
<div class="span3">Actions</div>
</div>
<div class="row-fluid statusResultsText">
<div class="span3 bold">
<span class="reportName">report2</span>
</div>
<div class="span2">429696109</div>
<div class="span3">2015-06-14 20:06:55</div>
<div class="span1">Done</div>
<div class="span3 statusResultsActions iconSize16 statusActionPad" id="374189255">
<i class="icon-download-alt mediumBlueIcon downloadIcon" id = "/decision_support/Status_retrieve_request.aspx?questionid=Q10201&applicationid=300&JobId=429696109&status=D&Extension=xls&filename=/Outbound06/q3bk06m_429696109_A14A90C6XB906X4F05X8539XDE448240CE97&reqname=report2,429696109" title="Download"></i>
</i>
<i class="icon-cog mediumBlueIcon modifydrequestIcon" id = "d_/decision_support/Report_Builder.aspx?country_cd=CA&qid=Q10201&exe_id=291&AppId=300&divid=1&JobId=429696109&reopen=true" title="Modify"></i>
</div>
</div>
<div class="row-fluid statusResultsText alternateBackground">
<div class="span3 bold">
<span class="reportName">Report Sun Jun 14 20:56:46 2015</span>
</div>
<div class="span2">429695641</div>
<div class="span3">2015-06-14 20:01:34</div>
<div class="span1">User Error</div>
<div class="span3 statusResultsActions iconSize16 statusActionPad" id="374188794">
</div>
</div>
</div>
</div>
</div>
# iterate through rows
Browser.divs.each do |row|
if row.div(:class => "span1").text == "Done"
report_name = row.span(:class => "reportName").text
row.divs.last.is.each do |i|
# move the mouse to <i> tag and click the <a> link, if <i> is an icon and <a> link is not present
Browser.driver.action.move_to(i.wd).click.perform
end
end
end

Resources