auto save javascript with rails - ruby-on-rails

I created a localstorage for the form on rails, when I tried the js code above for the
<textarea id="text"></textarea> tag it worked,
but when I tried the code like this, <%= f.text_area :title, class:"quill_container", id:"text" %> it only managed to retrieve the key, the value couldn't be retrieved
javascript code
<script type="text/javascript">
$(function() {
if (localStorage) {
var content = localStorage.getItem("autoSave");
if(content) {
$('#text').text(content);
}
}

Related

How to use material design text fields in rails

I am looking to use material design text field in rails in order to have the field's placeholder shifting to the top when the user start typing.
I do get the field to show up properly in rails straight from the example, but I DO NOT KNOW HOW TO ADAPT IT TO RAILS simple_form component.
application.html.erb
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
<script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>
in my form.html.erb
<%= f.input :title, label: false %>
<%= f.collection_select(:color, Color.all, :id, :name) %>
It shoudl look like this:
<form action="#">
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" id="sample3">
<label class="mdl-textfield__label" for="sample3">Text...</label>
</div>
</form>
I haven't use simple_form before, but looking at the docs, something like this should work.
<%= simple_for_form #user do |f| %>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<%= f.input_field :username, input_html: { class: 'mdl-textfield__input'} %>
<%= f.label :username, input_html: { class: 'mdl-textfield__label'} %>
</div>
<% end %>
If you want to create the whole div with just f.input_field you could look into custom inputs
You might be able to do something like this inside of a custom input
template.content_tag(:div class: 'mdl-textfield mdl-js-textfield mdl-textfield--floating-label') do
# text_field_input_code
# label_input_code
end
When I get you right, you are looking for "Float Labels"
This can normally be achieved with a mixture of JS and CSS, like described here.
In my own Rails application, where I also use simple_form, I have used the following code to achieve this pattern:
JS (jQuery):
// FLOATING LABLES:
$(document).on('turbolinks:load', function () {
$('.form-group.string').addClass('float-labels'); // removes all labels from the form (removing with js due to old browsers & disabled JS)
$('.form-group.string input.form-control').each( function (index, value) {
addRemoveFloatLable($(this)); // bring back labels for already filled forms (edit).
});
});
$(document).on('input keyup', '.form-group.string input', function () {
if( $(this).val().length <= 1 ) { // change only needed in case first char gets added (or latest gets removed)
addRemoveFloatLable($(this));
}
});
function addRemoveFloatLable($element) {
if ( $element.val() == '' ) { // input field is empty.
$element.parents('.form-group').removeClass('show-label');
} else {
$element.parents('.form-group').addClass('show-label');
}
}
CSS:
.form-group.string.float-labels {
label {
opacity: 0;
}
}
.form-group.string.float-labels.show-label {
label {
opacity: 1;
-webkit-transition: opacity 0.3s linear;
transition: opacity 0.3s linear;
}
}
I would like to recommend this tutorial, I have followed it and it works fine for me... hope this helps,
https://www.webascender.com/blog/tutorial-using-materialize-ruby-rails-simple-form/
Also have a look at
how to style simple_form with material design or custom css

Pass data from Rails template to Vue Instance

I've been trying to pass data from my Rails view to the Vue component as described here
Everything works much as expected, but I'm rather stumped as to how to access the data that I'm passing in via props. Not appearing in the Vue developer tools anywhere and I'm not able to find it by fiddling with/inside the Vue object.
Could someone point me in the right direction. I'm fairly green with Vue, so struggling to even know what to search for :/
show.html.erb
<%= javascript_pack_tag 'test_vue' %>
<%= stylesheet_pack_tag 'test_vue' %>
<%= content_tag :div, id: "test", data: {
message: "this wont!",
name: "nor will this!" }.to_json do %>
<% end %>
test.vue
<template>
<div id="app">
<p>{{test}}{{message}}{{name}}</p>
</div>
</template>
<script>
export default {
data: function () {
return {
test: 'This will display',
}
}
}
</script>
<style>
</style>
test_vue.js
import Vue from 'vue'
import Test from './test.vue'
document.addEventListener('DOMContentLoaded', () => {
const node = document.getElementById('test')
const props = JSON.parse(node.getAttribute('data'))
new Vue({
render: h => h(Test, { props })
}).$mount('#test');
})
Looks like all you need to do is declare the properties in your component:
<template>
<div id="app">
<p>{{test}}{{message}}{{name}}</p>
</div>
</template>
<script>
export default {
props: ["message","name"],
data: function () {
return {
test: 'This will display',
}
}
}
</script>
<style>
</style>
This would be the relevant documentation.
A child component needs to explicitly declare the props it expects to
receive using the props option

Google charts does not always load in first attempt

I ask advice. Google chart is not always loaded on the first attempt ... how to solve this problem?
demo
view:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Time', 'TempC'],
<% #data.css("hourly").each do |hrly| %>
['<%= hrly.css("time").text %>',<%= hrly.css("tempC").text %>],
<% end %>
]);
var options = {
title: 'Temperature forecast'
};
var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
<div id="chart_div" style="width: 100%; height: auto;"></div>
controller
class WwoController < ApplicationController
def weather
require 'nokogiri'
url = "https://api.worldweatheronline.com/premium/v1/weather.ashx?q=59.94%2C30.31&num_of_days=4&key=***********************************"
#data = Nokogiri::XML(open(url))
end
end
If you use turbolinks, try to disable it in that page, because I have similar problems with google maps apis
to disable turbolinks you can add this to your application.html.erb
<body <%= yield(:body_attributes) %>>
then in your view.html.erb add this in first line
<%= content_for(:body_attributes, 'data-no-turbolink') %>
you can also disable turbolink with link_to
<%= link_to 'link_name', your_link_path, 'data-no-turbolink' => true %>
if you use rails/turbolinks 5
change data-no-turbolink into data-turbolinks and switch the boolean value
also try to put your javascript in the bottom. to make it loaded after the html dom.

Rails CKeditor not submitting data

I used the following statement to create a ckeditor:
= f.text_area :message, :class=>'ckeditor', :ckeditor => {:language => "us"}
if I use f.cktextarea as specified in https://github.com/galetahub/ckeditor, I get only a normal text area.
and if I call .ckeditor() on the text area also I dont get one.
I get ckeditor only if I add ckeditor class to the text area.
But even if I have a ckeditor, the value isnt being submitted when I submit the form.
What should I do?
On inspection I get my text area as:
<textarea class="ckeditor" cols="40" id="email_message" name="email[message]" rows="20" style="visibility: hidden; display: none;"></textarea>
followed by the ckeditor code...
How should I solve this?
Try this:
<%= f.cktext_area :message, :ckeditor => {:language => "us"} %>
<script type='text/javascript' charset='UTF-8'>
$(document).ready(function(){
$('form[data-remote]').bind("ajax:before", function(){
for (instance in CKEDITOR.instances){
CKEDITOR.instances[instance].updateElement();
}
});
});
</script>
$('.formSubmit').submit( function()
{
var data = CKEDITOR.instances.editor1.getData();
$.ajax({
type: 'POST',
url: 'ck_bienban_1_luu.php',// url of phpcode save
data: {
data: data,
},
success: function() {
//
},
});
return(false);
}
);
.formSubmit is class name of form,
var data = CKEDITOR.instances.editor1.getData(); this is data of textarea

How to make this javascript unobtrusive?

I have this javascript code, from google charts api right in the bottom of my view :
<div id='visualization'></div>
...
<script type="text/javascript">
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable(<%=raw #pie_gender %>)
// Create and draw the visualization.
new google.visualization.PieChart(document.getElementById('visualization')).
draw(data, {title:"Men and Women"});
}
google.setOnLoadCallback(drawVisualization);
</script>
I've tried to put this js code in my assets folder under a .js file, and include it in my headers, as well as replacing <%=raw #pie_gender %> with this.getAttribute('data-message') and putting my div as ', but then i get a javascript error "getAttribute" does not exist for object window
I have also tried to pass my array as an input argument like : onload="drawVisualization(<%=raw #pie_gender %>), but then I get "Error: Not an array"
What might I be doing wrong ?
EDIT
#pie_gender = [['Gender', 'Occurences']['M', 10]['F', 5]]
Based on example from google
EDIT 2
If i print the json output
<% logger.debug "Pie Gender : #{#pie_gender.to_json}" %>
<div id="visualization" onload="drawVisualization(<%= #pie_gender.to_json %>)" > </div>
,it seems just fine :
Pie Gender : [["Gender","Receipts"],["",25000],["F",8658]]
but it seems that something happens while sending this as an argument to my js function, because it still says that message is not an array :
function drawVisualization(message) {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable(message);
// Create and draw the visualization.
new google.visualization.PieChart(document.getElementById('visualization')).
draw(data, {title:"Men and Women"});
}
google.setOnLoadCallback(drawVisualization);
To workaround this, I inserted my javascript code in a partial
_googlescript.html.erb
<script type="text/javascript">
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable(<%=raw data_array %>)
// Create and draw the visualization.
new google.visualization.PieChart(document.getElementById('visualization')).
draw(data, {title:"Men and Women"});
}
google.setOnLoadCallback(drawVisualization);
</script>
in my view I rendered the partial in the bottom of the page, and removed the onload, which just seemed not to be doing a thing... :
<div id="visualization" > </div>
...
<%= render partial: 'shared/googlescript', locals: {data_array:#pie_gender} %>
Now i can see the chart again...but i still feel there is a better answer to my question.

Resources