I am using Stripe elements and the form is not displaying in my rails app.
I have tried many suggestions and still no improvement. I am
using ruby 2.3 & Rails 5.2.3 but not bootstrap.
charges.js
document.addEventListener("turbolinks:load", function() {
const public_key = document.querySelector("meta[name='stripe-public-
key']").content;
const stripe = Stripe(public_key);
const elements = stripe.elements();
const style = {
base: {
color: '#32325d',
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
const card = elements.create('card', {style: style});
card.mount('#card-element');
card.addEventListener('change', ({error}) => {
const displayError = document.getElementById('card-errors');
if (error) {
displayError.textContent = error.message;
} else {
displayError.textContent = '';
}
});
const form = document.getElementById('new_job');
form.addEventListener('submit', async (event) => {
event.preventDefault();
const {token, error} = await stripe.createToken(card);
if (error) {
// Inform the customer that there was an error.
const errorElement = document.getElementById('card-errors');
errorElement.textContent = error.message;
} else {
// Send the token to your server.
stripeTokenHandler(token);
}
});
const stripeTokenHandler = (token) => {
// Insert the token ID into the form so it gets submitted to the server
const form = document.getElementById('new_job');
const hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
["brand", "exp_month", "exp_year", "last4"].forEach(function(field) {
addFieldToForm(form, token, field);
});
// Submit the form
form.submit();
}
function addFieldToForm(form, token, field) {
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', "user[card_" + field + "]");
hiddenInput.setAttribute('value', token.card[field]);
form.appendChild(hiddenInput);
}
});
application.html.erb
<!DOCTYPE html>
<html>
<head>
<title></title>
<%= csrf_meta_tags %>
<meta name="viewport" content="width=device-width, initial-scale=1">
<%= stylesheet_link_tag 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css', 'https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css' %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', "https://js.stripe.com/v2/", "https://js.stripe.com/v3/", 'data-turbolinks-track': 'reload' %>
<%= tag :meta, name: "stripe-public-key", content: Figaro.env.stripe_publishable_key %>
</head>
<body>
</body
</html>
payments form
<div class="form-row">
<label for="card-element" class="label">
Enter credit or debit card
</label>
<div id="card-element" class="form-control">
<!-- a Stripe Element will be inserted here. -->
</div>
<!-- used to display Element errors -->
<div id="card-errors" role="alert"></div>
</div>
For using stripe elements, you need to run your application with https, read more in stripe documentations https://stripe.com/docs/stripe-js/elements/quickstart#http-requirements
Related
So i have a view model like this
public class TestViewModel
{
public DateTime? StartDate { get; set; }
public DateTime StartDate2 { get; set; }
}
With that viewmodel I expect that if I send "NULL" to those properties via JSON from ajax, then value for those properties are StartDate = null and StartDate2 = {01/01/0001 00.00.00}
This works as expected in my local machine, but on my server it returns error Bad Request
I know my server return Bad Request because of the model binding thing
Why does my server behave differently with my local machine ?
And how do I fix this ?
EDIT :
By the way, if I change the StartDate and StartDate2 type to string. It has no error, the code works perfectly
Here's my action in controller
public ActionResult TestAction(List<TestViewModel> p_viewModel)
{
//The code actually does not reach here, because it fail on model binding ?
// bla bla bla some logic here
}
and here's my javascript
function getData()
{
let datas = [];
$("#tableListMeeting tbody tr").each(function (i, row) {
let rowItem = $(row);
let startDate = rowItem.find(`input[name$=".StartDate"]`).val();
//change date format
startDate = (startDate == "") ? null : moment(startDate, "DD-MM-YYYY").format("YYYY/MM/DD");
let item = {
StartDate: startDate
};
datas.push(item);
});
return datas;
}
function onButtonClick(){
let data = getData();
let URL_TO_ACTION = "......"; //url to my action
$.ajax({
url: URL_TO_ACTION,
type: 'post',
datatype: 'json',
data: JSON.stringify(data),
contentType: 'application/json; charset=utf-8',
success: function (response) {
console.log("ajax local event 'sucess'");
console.log(response);
},
error: function (jqXHR, ajaxOptions, thrownError) {
if (jqXHR.status == 400) {
let a = jqXHR.responseText;
//logic to print error message
} else {
alert("Something went wrong, please try again");
}
},
beforeSend: function () {
console.log("ajax local event 'beforeSend'");
}
}
You should show more code in order to find out what's wrong.
Here is the fiddle with the working example for your View model.
https://dotnetfiddle.net/Eu7ayF
Controller:
[HttpPost]
public JsonResult GetAnswer(TestViewModel data)
{
Console.WriteLine(data.StartDate);
return Json(data);
}
View with ajax post.
#model HelloWorldMvcApp.TestViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<!-- template from http://getbootstrap.com/getting-started -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap 101 Template</title>
<!-- CSS Includes -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<style type="text/css">
.field-validation-error {
color: #ff0000;
}
</style>
</head>
<body>
<div class="container">
<div class="col-md-6 col-md-offset-3">
<h1>Hello Stranger</h1>
#using (Html.BeginForm())
{
<div class="form-group">
#Html.LabelFor(m => m.StartDate)
#Html.TextBoxFor(model => model.StartDate, new {#class="form-control"})
#Html.ValidationMessageFor(model => model.StartDate)
</div>
<div class="form-group">
#Html.LabelFor(m => m.StartDate2)
#Html.TextBoxFor(model => model.StartDate2, new {#class="form-control"})
#Html.ValidationMessageFor(model => model.StartDate2)
</div>
<button type="button" class="btn btn-success submit">Post Ajax</button>
}
<br/><br/>
<div class="alert alert-warning fade">
<img src="http://entechprod.blob.core.windows.net/dotnetfiddle/morpheus.jpg" style="max-width:100%;"/><br/><br/>
<strong><span class="alert-content"></span></strong>
</div>
</div>
</div>
<!-- JS includes -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.min.js"></script>
<script type="text/javascript">
$(function(){
$('.submit').click(function(){
if($('form').valid()) {
$.ajax({
url: '#Url.RouteUrl(new{ action="GetAnswer", controller="Home"})',
data: {startDate2: $('#startDate2').val(), startDate: $('#startDate').val()},
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function(resp) {
alert(resp.StartDate);
alert(resp.StartDate2);
}});
}
});
});
</script>
</body>
</html>
I'm building a mobile web that needs to read device orientation value from iphone, and the other webpage that gets the value.
This project is going to be displayed in the exhibition, so I'm planning to use USB to connect mobile and the macbook through localhost for realtime response.
But when I see it on iphone by connecting it to my localhost, device orientation value cannot be read.
https://medium.com/#wiekatz/testing-web-applications-running-on-localhost-with-an-iphone-7db6258b8f2
I followed this instruction to connect the device to localhost, and the connection works fine so that I can see it on my phone. I checked that other features like recognizing which button has been clicked are working fine in realtime.
I could see device orientation working when I deploy this to other domain and check on the phone, but I need to make this working through localhost.
Let me know if there's any clue what is causing this!
//mobile.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<title>Mobile PtoR</title>
<link rel="stylesheet" href="mobile_style.css" />
<script src="https://www.gstatic.com/firebasejs/6.3.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/6.3.1/firebase-firestore.js"></script>
<style></style>
</head>
<body>
<div id="closewrapper"><button id="closebutton">x</button></div>
<div class="iconwrapper">
<div class="icons" id="AppBank"><p>Bank</p></div>
<div class="icons" id="AppWeather"><p>Weather</p></div>
<div class="icons" id="AppDict"><p>Dictionary</p></div>
<div class="icons" id="AppFb"><p>Facebook</p></div>
<div class="icons" id="AppCal"><p>Calendar</p></div>
</div>
<div class="sensorcheck">
<h1>Device Orientation API</h1>
<span id="do-unsupported" class="hidden"
>deviceorientation event not supported</span
>
<span id="dm-unsupported" class="hidden"
>devicemotion event not supported</span
>
<span id="cnc-unsupported" class="hidden"
>compassneedscalibration event not supported</span
>
<div id="do-results">
<div id="cube" class="cube">
<div class="face one">1</div>
<div class="face two">2</div>
<div class="face three">3</div>
<div class="face four">4</div>
<div class="face five">5</div>
<div class="face six">6</div>
</div>
<div id="do-info" class="hidden">
<p>
Coordinates: (<span id="beta" class="value">null</span>,
<span id="gamma" class="value">null</span>,
<span id="alpha" class="value">null</span>)
<br />
Position absolute?
<span id="is-absolute" class="value">unavailable</span>
</p>
</div>
<div id="dm-info" class="hidden">
<p>
Acceleration: (<span id="acceleration-x" class="value">null</span>,
<span id="acceleration-y" class="value">null</span>,
<span id="acceleration-z" class="value">null</span>) m/s<sup>2</sup>
</p>
<p>
Acceleration including gravity: (<span
id="acceleration-including-gravity-x"
class="value"
>null</span
>,
<span id="acceleration-including-gravity-y" class="value">null</span>,
<span id="acceleration-including-gravity-z" class="value">null</span>)
m/s<sup>2</sup>
</p>
<p>
Rotation rate: (<span id="rotation-rate-beta" class="value">null</span
>, <span id="rotation-rate-gamma" class="value">null</span>,
<span id="rotation-rate-alpha" class="value">null</span>)
</p>
<p>Interval: <span id="interval" class="value">0</span> milliseconds</p>
</div>
</div>
</div>
<script>
if (!window.DeviceOrientationEvent) {
document.getElementById("do-unsupported").classList.remove("hidden")
} else {
document.getElementById("do-info").classList.remove("hidden")
window.addEventListener("deviceorientation", function(event) {
document.getElementById(
"cube"
).style.webkitTransform = document.getElementById(
"cube"
).style.transform =
"rotateX(" +
event.beta +
"deg) " +
"rotateY(" +
event.gamma +
"deg) " +
"rotateZ(" +
event.alpha +
"deg)"
document.getElementById("beta").innerHTML = Math.round(event.beta)
document.getElementById("gamma").innerHTML = Math.round(event.gamma)
document.getElementById("alpha").innerHTML = Math.round(event.alpha)
document.getElementById("is-absolute").innerHTML = event.absolute
? "true"
: "false"
})
}
</script>
<!-- Custom fuctions of firebase-->
<script src="mobileFirebase.js"></script>
</body>
</html>
//mobileFirebase.js
//the value is passed to firebase
var firebaseConfig = {
--------
}
firebase.initializeApp(firebaseConfig)
var firestore = firebase.firestore()
/* define things to be used*/
const AppBank = document.querySelector("#AppBank")
const AppWeather = document.querySelector("#AppWeather")
const AppDict = document.querySelector("#AppDict")
const AppFb = document.querySelector("#AppFb")
const AppCal = document.querySelector("#AppCal")
const closewrapper = document.querySelector("#closewrapper")
const closebutton = document.querySelector("#closebutton")
//const CurrentStatus = "landing"
const DOsensorRef = firestore.doc("status/DOsensor")
const docRef = firestore.doc("status/ClickStatus")
/* device orientation */
if (!window.DeviceOrientationEvent) {
document.getElementById("do-unsupported").classList.remove("hidden")
} else {
document.getElementById("do-info").classList.remove("hidden")
window.addEventListener("deviceorientation", function(event) {
const val_beta = Math.round(event.beta)
const val_gamma = Math.round(event.gamma)
const val_alpha = Math.round(event.alpha)
console.log(
"beta : ",
val_beta,
"gamma : ",
val_gamma,
"alpha : ",
val_alpha
)
DOsensorRef.set({
fire_beta: val_beta,
fire_alpha: val_alpha,
fire_gamma: val_gamma
})
.then(function() {
console.log("in sync")
})
.catch(function(error) {
console.log(error)
})
})
}
/* status recognize */
closebutton.addEventListener("click", function(){
closewrapper.style.display="none"
const CurrentStatus = "Landing"
docRef.set({
AppStatus: CurrentStatus
})
.then(function() {
console.log("Status changed!")
})
.catch(function(error) {
console.log("got an error: ", error)
})
})
AppBank.addEventListener("click", function() {
const CurrentStatus = "Bank"
docRef.set({
AppStatus: CurrentStatus
})
.then(function() {
console.log("Status changed!")
})
.catch(function(error) {
console.log("got an error: ", error)
})
closewrapper.style.display="block"
})
AppWeather.addEventListener("click", function() {
const CurrentStatus = "Weather"
docRef.set({
AppStatus: CurrentStatus
})
.then(function() {
console.log("Status changed!")
})
.catch(function(error) {
console.log("got an error: ", error)
})
closewrapper.style.display="block"
})
AppDict.addEventListener("click", function() {
const CurrentStatus = "Dictionary"
docRef.set({
AppStatus: CurrentStatus
})
.then(function() {
console.log("Status changed!")
})
.catch(function(error) {
console.log("got an error: ", error)
})
closewrapper.style.display="block"
})
AppFb.addEventListener("click", function() {
const CurrentStatus = "Facebook"
docRef.set({
AppStatus: CurrentStatus
})
.then(function() {
console.log("Status changed!")
})
.catch(function(error) {
console.log("got an error: ", error)
})
closewrapper.style.display="block"
})
AppCal.addEventListener("click", function() {
const CurrentStatus = "Calendar"
docRef.set({
AppStatus: CurrentStatus
})
.then(function() {
console.log("Status changed!")
})
.catch(function(error) {
console.log("got an error: ", error)
})
closewrapper.style.display="block"
})
I had the same Problem yesterday. Your localhost probably does not run on https but on http. So certain features as device orientation gets blocked. You are only able to use them in a secure context.
Easy solution is to tunnel your local server to the outside e.g. with https://localtunnel.github.io/www/
or make your own secure certificate for your local webserver. Maybe you can find some infos here.
I'm trying to get Stripe.js to work on my rails app. I am using stripe elements. I have followed the instructions on the stripe docs. The form card input is not showing up where it should. It just shows the submit button.
I am trying to place the Stripe form in an existing rails form I have.
<!DOCTYPE html>
<html>
<head>
<title>Bennett</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<script src="https://js.stripe.com/v3/"></script>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<%= render '/home/nav' %>
<%= yield %>
</br>
<%= render '/home/footer' %>
</body>
</html>
VISITS/_FORM
<%= simple_form_for([#service, #visit]) do |f| %>
<%= f.error_notification %>
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
<%= f.input :visit_date, as: :date , :label => "Service date:"%>
<%= f.input :visit_time, as: :time , :label => "Service time:" %>
<%= f.input :note, :label => "Anything we should know?" %>
<%= render 'charges/payment-form' %>
<%= f.button :submit, class:'btn btn-bennett' %>
<% end %>
_PAYMENT-FORM
<form action="/charge" method="post" id="payment-form">
<div class="form-row">
<label for="card-element">
Credit or debit card
</label>
<div id="card-element">
<!-- A Stripe Element will be inserted here. -->
</div>
<!-- Used to display form errors. -->
<div id="card-errors" role="alert"></div>
</div>
<button>Submit Payment</button>
</form>
CHARGE.JS
// Create a Stripe client.
var stripe = Stripe('XXXXXXXXXXXXXX');
// Create an instance of Elements.
var elements = stripe.elements({
fonts: [
{
cssSrc: 'https://fonts.googleapis.com/css?family=Roboto',
},
],
// Stripe's examples are localized to specific languages, but if
// you wish to have Elements automatically detect your user's locale,
// use `locale: 'auto'` instead.
locale: window.__exampleLocale
});
// Custom styling can be passed to options when creating an Element.
// (Note that this demo uses a wider set of styles than the guide below.)
var style = {
base: {
color: '#32325d',
lineHeight: '18px',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
// Create an instance of the card Element.
var card = elements.create('card', {style: style});
// Add an instance of the card Element into the `card-element` <div>.
card.mount('#card-element');
// Handle real-time validation errors from the card Element.
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
// Handle form submission.
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.createToken(card).then(function(result) {
if (result.error) {
// Inform the user if there was an error.
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// Send the token to your server.
stripeTokenHandler(result.token);
}
});
});
// Submit the form with the token ID.
function stripeTokenHandler(token) {
// Insert the token ID into the form so it gets submitted to the server
var form = document.getElementById('payment-form');
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
// Submit the form
form.submit();
}
I don't know why the form is not showing up.
Basically what I am aiming to get accomplished is have it so when I create a new 'Visit' through the Visit form, I also process a payment through stripe and it all gets submitted through one button. Maybe someone can help me with that also?
I had the same problem, solved it by adding this to my css:
.StripeElement{
min-width: 300px;
}
It looks like you aren't waiting for the page to load to execute your script, hence the error that it can't find #card-element.
You should wrap your code to wait for the page load:
document.addEventListener('turbolinks:load',function () {
....Your code
}
I'm using Rails 5.1 + Webpack running Vue 2. I'm fairly new to Vue, not so new to Rails.
I'm building a navbar component starting from the Bulma navbar. My objective is to be able to dynamically create links in the navbar by simply adding a navlink element nested within.
In my application.html.erb I have already created this structure (navlink nested inside navbar).
In hello_vue.js I'm initializing the Vue components and assigning them to a root element (one for the navbar and one for the rest of the content).
In navbar.vue, I'd like to iterate through all the and create a menu item accordingly. In order to do so, I added an empty navlinks data to navbar that I want to populate once it gets mounted() by fetching all its children (the nested navlink tags).
This is however not working, whenever I reference this.$children I get an empty array. Any idea why is this happening?
This is all the code.
application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>RailsVue</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= stylesheet_pack_tag 'hello_vue' %>
</head>
<body>
<div id="navbar-container">
<navbar>
<navlink href="http://google.com">
Link 1
</navlink>
<navlink href="http://facebook.com">
Link 2
</navlink>
</navbar>
</div>
<%= yield %>
<%= javascript_pack_tag 'hello_vue' %>
</body>
</html>
hello_vue.js
import Vue from 'vue/dist/vue.esm'
import App from './app.vue'
import Navlink from './components/navlink.vue'
import Navbar from './components/navbar.vue'
const navbar = new Vue({
el: "#navbar-container",
components: { Navbar, Navlink }
})
const app = new Vue({
el: '#hello',
data: {
message: "Can you say hello?"
},
components: { App }
})
navbar.vue
<template>
<div>
<nav class="navbar is-transparent">
<div class="navbar-brand">
<a class="navbar-item" href="http://bulma.io">
<img src="http://bulma.io/images/bulma-logo.png" alt="Bulma: a modern CSS framework based on Flexbox" width="112" height="28">
</a>
<div class="navbar-burger burger" data-target="navMenuTransparentExample">
<span></span>
<span></span>
<span></span>
</div>
</div>
<div id="navMenuTransparentExample" class="navbar-menu">
<div class="navbar-start">
<a v-for="navlink in navlinks" class="navbar-item" :href="navlink.href">
<slot></slot>
</a>
</div>
</div>
</nav>
</div>
</template>
<script>
import Navlink from './navlink.vue'
export default {
name: "Navbar",
data: function () {
return {
navlinks: []
}
},
created: function(){
// let children = this.$children;
console.log(this.$children);
// this.navlinks = this.$children;
// this.navlinks = this.$children;
}
}
</script>
navlink.vue
<template>
<div class="navlink">
<slot></slot>
</div>
</template>
<script>
export default {
name: "Navlink"
}
</script>
Instead of created hook, use mounted hook, you can able to get this.$children
mounted : function(){
// let children = this.$children;
console.log(this.$children);
// this.navlinks = this.$children;
// this.navlinks = this.$children;
}
You can modify components to achieve your requirement as follows
application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>RailsVue</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= stylesheet_pack_tag 'hello_vue' %>
</head>
<body>
<div id="navbar-container">
<navbar>
<navlink>
<a class="navbar-item" href="http://google.com">
Link 1
</a>
</navlink>
<navlink>
<a class="navbar-item" href="http://facebook.com">
Link 2
</a>
</navlink>
</navbar>
</div>
<%= yield %>
<%= javascript_pack_tag 'hello_vue' %>
</body>
</html>
hello_vue.js
import Vue from 'vue/dist/vue.esm'
import App from './app.vue'
import Navlink from './components/navlink.vue'
import Navbar from './components/navbar.vue'
const navbar = new Vue({
el: "#navbar-container",
components: { Navbar, Navlink }
})
navbar.vue
<template>
<div>
<nav class="navbar is-transparent">
<div class="navbar-brand">
<a class="navbar-item" href="http://bulma.io">
<img src="http://bulma.io/images/bulma-logo.png" alt="Bulma: a modern CSS framework based on Flexbox"
width="112" height="28">
</a>
<div class="navbar-burger burger" data-target="navMenuTransparentExample">
<span></span>
<span></span>
<span></span>
</div>
</div>
<slot></slot>
</nav>
</div>
</template>
<script>
// import Navlink from './navlink.vue'
export default {
name: 'Navbar',
data: function () {
return {
navlinks: []
}
},
mounted: function () {
// let children = this.$children;
// console.log(this)
console.log(this.$children)
// console.log(this.$root.$children[0])
// this.navlinks = this.$children
// this.navlinks = this.$children;
}
}
</script>
navlink.vue
<template>
<div class="navlink">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'Navlink'
}
</script>
I am working on a task assignment board and i have a problem on shifting existing tabs (accordion) between certain div's ... The scope variables list is getting updated properly and the code works fine when i am jQuery accordion .But when i use an angular js accordion ,
The shifting of the accordion tabs gets duplicated .
// main HTML content
<!DOCTYPE html>
<html ng-app="App">
<title>Task WhiteBoard</title>
<head>
<meta charset="utf-8" />
<meta name="description" content="AngularJS + jQuery UI Drag-n-Drop" />
<link rel="stylesheet/less" type="text/css" href="css/main.less" />
<link href="css/zippy.css" rel="stylesheet">
<link href="css/jquery-ui-1.9.2.custom.min.css" rel="stylesheet"
type="text/css" />
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/jquery-1.8.1.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<script src="js/angular.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
<script src="js/less-1.1.6.min.js"></script>
<meta charset="utf-8" />
<title>Angular Drag and Drop</title>
</head>
<body ng-controller="dndCtrl" ng-cloak>
<h3>Task Whiteboard</h3>
<div class='list1' droppable value='1' >
<div class='header'>
Free Tasks
</div>
<div class="below-header">
</div>
<div ng-repeat="item in list1" data-index="{{$index}}" draggable>
<div class="zippy" zippy-title="{{item.name}}">
{{item.content.newLabel}} <br/>
{{item.content.desc}} <br/>
{{item.content.effort}} <br/>
{{item.content.owner}} <br/>
{{item.content.issues}} <br/>
{{item.content.comments}} <br/>
{{item.content.dependency}} <br/>
</div>
</div>
</div>
<div class='list2' droppable value='2'>
<div class='header'>
Claimed Tasks
</div>
<div class="below-header">
</div>
<div ng-repeat="item in list2" data-index="{{$index}}" draggable>
<div class="zippy" zippy-title="{{item.name}}">
{{item.content.newLabel}} <br/>
{{item.content.desc}} <br/>
{{item.content.effort}} <br/>
{{item.content.owner}} <br/>
{{item.content.issues}} <br/>
{{item.content.comments}} <br/>
{{item.content.dependency}} <br/>
</div>
</div>
</div>
<div class='list3' droppable value='3'>
<div class='header'>
Completed Tasks
</div>
<div class="below-header">
</div>
<div ng-repeat="item in list3" data-index="{{$index}}" draggable>
<div class="zippy" zippy-title="{{item.name}}">
{{item.content.newLabel}} <br/>
{{item.content.desc}} <br/>
{{item.content.effort}} <br/>
{{item.content.owner}} <br/>
{{item.content.issues}} <br/>
{{item.content.comments}} <br/>
{{item.content.dependency}} <br/>
</div>
</div>
</div>
<div style="clear:both;">
list 1 size : {{list1.length}} <br/>
list 2 size : {{list2.length}} <br/>
list 3 size : {{list3.length}} <br/>
</div>
</body>
</html>
// services.js
//This makes any element droppable
//Usage: <div droppable></div>
App.directive('droppable', function ($compile) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
scope.$watch(function (value) {
//This makes an element Droppable
element.droppable({
drop: function (event, ui) {
var dragIndex =
angular.element(ui.draggable).data('index');
if(angular.element(ui.draggable).parent().hasClass('list1') &&
element.attr('value')=='2') {
scope.list2.push(scope.list1[dragIndex]);
scope.list1.splice(dragIndex, 1);
}
else if (angular.element(ui.draggable).parent().hasClass('list2') &&
element.attr('value')=='3') {
scope.list3.push(scope.list2[dragIndex]); scope.list2.splice(dragIndex, 1);
// alert("list2 size : "+scope.list2.length);
}
else if (angular.element(ui.draggable).parent().hasClass('list2') && element.attr('value')=='1') {
scope.list1.push(scope.list2[dragIndex]);
scope.list2.splice(dragIndex, 1);
// alert("list3 size : "+scope.list3.length);
}
scope.$apply();
}
});
});
}
};
});
//zippy directive to give an accordion feel
App.directive('zippy', function(){
return {
restrict: 'C',
// This HTML will replace the zippy directive.
replace: true,
transclude: true,
scope:{ title:'#zippyTitle' },
template:'<div>'+
'<div class="title">{{title}}</div>'+
'<div class="body" ng-transclude></div><hr/>'+
'</div>',
// The linking function will add behavior to the template
link: function(scope, element, attrs) {
// Title element
var title = angular.element(element.children()[0]),
// Opened / closed state
opened = true;
// Clicking on title should open/close the zippy
title.bind('click', toggle);
// Toggle the closed/opened state
function toggle() {
opened = !opened;
element.removeClass(opened ? 'closed' : 'opened');
element.addClass(opened ? 'opened' : 'closed');
}
// initialize the zippy
toggle();
}
}
});
// In controller .js
$scope.list1 = [
{
name: 'Intelligent Design',
content: {
newLabel : 'Create New Label',
desc : 'Add Description',
effort : 'Burned effort',
owner : 'Owner',
issues : 'Issues',
comments : 'Comments',
dependency : 'Dependency'
}
},
{
name: 'Good Artist\'s Copy',
content: {
newLabel : 'Create New Label',
desc : 'Add Description',
effort : 'Burned effort',
owner : 'Owner',
issues : 'Issues',
comments : 'Comments',
dependency : 'Dependency'
}
},
{
name: 'Task Creation',
content: {
newLabel : 'Create New Label',
desc : 'Add Description',
effort : 'Burned effort',
owner : 'Owner',
issues : 'Issues',
comments : 'Comments',
dependency : 'Dependency'
}
}]
$scope.list2 = [
{
name: 'Task4',
content: {
newLabel : 'Create New Label',
desc : 'Add Description',
effort : 'Burned effort',
owner : 'Owner',
issues : 'Issues',
comments : 'Comments',
dependency : 'Dependency'
}
}]
$scope.list3 = [];