Angular-file-upload and Rails with Carrierwave - javascript

I've been trying to workout upload photo using angular-file-upload and Rails with the carrierwave .. I got an error Converting circular structure to JSON, I already google the problem it seems I didn't get the idea how to remove that I error. I just followed the tutorial in https://github.com/nervgh/angular-file-upload/blob/master/examples/simple/index.html.
Angular
$scope.sp = { serviceprovider: {
avatar: { name: $scope.uploader = new FileUploader() }
},
categories: [],
clearances: [2]
};
$scope.registerProvider = function registerProvider () {
console.log($scope.sp);
$http.post('/serviceproviders/new_serviceprovider/', $scope.sp )
.success ( function onLink ( response) {
location.href = "index";
})
.error ( function onLink ( response ) {
console.log(response)
});
}
HTML
<section ng-controller="RegisterServiceProviderCtrl">
<!-- multistep form -->
<form id="msform" ng-submit="registerProvider()" novalidate>
<!-- progressbar -->
<ul id="progressbar">
<li class="active">Authentication</li>
<li>Personal Information</li>
<li>Professional Skill</li>
</ul>
<!-- fieldsets -->
<fieldset>
<h2 class="fs-title">Create your account</h2>
<!-- <h3 class="fs-subtitle">This is step 1</h3> -->
<div class="row">
<div class="col-xs-12">
<center><div class="fileinput fileinput-new" data-provides="fileinput">
<div class="fileinput-preview thumbnail" data-trigger="fileinput" style="width: 200px; height: 150px;"></div>
<div>
<span class="btn btn-primary btn-file"><span class="fileinput-new">Select image</span><span class="fileinput-exists">Change</span><input type="file" nv-file-select uploader="uploader"/><%#= f.file_field :avatar %></span>
Remove
</div>
</div></center>
</div>
</div>
..... code

Related

why the value of productsCenter variable is null?

i want to know wher the error came from, i'm trying to make an ecommerce project with vanilla javaScript, when i start display the products, json data is fetched correctly as a first step, but when i excecuted displayProducts() function it didn't work!
the error message i got:
Uncaught (in promise) TypeError: Cannot set property 'innerHTML' of null.
i tried console.log(document.querySelector("products-center")) but the result was null, i also made sure that the js script tag is after html tags.
const productsCenter = document.querySelector("products-center");
class Displayproducts {
async getData() {
try {
let response = await fetch("products.json");
let data = await response.json();
let products = data.items;
let mapped = products.map((el) => {
const { title, price } = el.fields;
const image = el.fields.image.fields.file.url;
const id = el.sys.id;
return { title, price, image, id };
});
return mapped;
} catch (err) {
console.log(err);
}
}
}
class UI {
displayProducts(products) {
products.forEach((product) => {
productsCenter.innerHTML = `<article class="product">
<div class="img-container">
<img
src="${product.image}"
alt="product"
class="product-img"
/>
<button class="bag-btn">
<i class="fas fa-shopping-cart"></i>
add to bag
</button>
</div>
<h3>${product.title}</h3>
<h4>${product.price}</h4>
</article>`;
});
}
}
window.onload = () => {
const product = new Displayproducts();
const ui = new UI();
product.getData().then((products) => {
ui.displayProducts(products);
});
};
<body>
<!-- start of nav bar -->
<nav class="navbar">
<div class="navbar-center">
<span class="nav-icon">
<i class="fas fa-bars"></i>
</span>
<!-- <img
src="https://i.pinimg.com/originals/dd/79/2d/dd792d5596291f410cb8e7ce10a7e91a.png"
alt="logo"
/> -->
<div class="cart-btn"></div>
<span class="nav-icon">
<i class="fas fa-cart-plus"></i>
</span>
<div class="cart-items">0</div>
</div>
</nav>
<!-- end of nav bar -->
<!-- start of header -->
<header class="hero">
<div class="banner">
<h1 class="banner-title">furniture collection</h1>
<button class="banner-btn">shop now</button>
</div>
</header>
<!-- end of header -->
<!-- start of cart -->
<div class="cart-overlay">
<div class="cart">
<span class="close-cart">
<i class="fas fa-window-close"></i>
</span>
<h2>your cart</h2>
<div class="content"></div>
<!-- start of cart item -->
<!-- end of cart item -->
</div>
</div>
<!-- end of cart -->
<!-- start of products-->
<section class="products">
<div class="section-title">
<h2>our products</h2>
</div>
<div class="products-center">
</div>
</section>
<!-- end of products -->
<script src="app.js"></script>
</body>
document.querySelector("products-center"); searches for a DOM element which tag is named "products-center" (something like: <products-center></products-center>). And since this doesn't exist, productsCenter doesn't contain any valid DOM, and so you cannot set its innerHTML.
I can see <div class="products-center"> in your HTML, so I guess you meant to use const productsCenter = document.querySelector(".products-center"); (note the .).

MVC Navigate to Another Page With JavaScript

When I click on a city in the map on my homepage, the corresponding screen opens as a pop-up. Then if I click on the body of this opened window I want to go to the detail page of the relevant project. But I could not set the JavaScript code.
My Index.cshtml:
#{ Html.RenderPartial("Map");}
<div class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form>
<div class="modal-body popupList">
</div>
</form>
</div>
</div>
<script>
$('g [type=city]').click(function (el) {
$('#turkey-map g [type="city"]').attr('activeChart', 0)
$(this).attr('activeChart', 1);
var cityid = $(this).attr('city_id');
$('.popupList').html('preparing content...');
$.ajax({
method: "get",
url: '#Url.Action("ProjectListPartial", "Home")',
data: { cityID: cityid, UnitID: #UnitID }
})
.done(function (msg) {
$('.popupList').html(msg);
$(".modal").modal();
});
});
</script>
And my ProjectListPartial.cshtml:
<div class="ProjectsPartial">
#foreach (var item in Model)
{
<div class="ProjectPartialBody" data-id="#item.ID">
<div class="portlet-body">
<div class="mt-element-list">
<div class="mt-list-head list-news ext-1 font-white bg-grey-gallery">
<div class="list-head-title-container">
<h5 class="list-title">#item.tbl_Unit.Name</h5>
<br />
<h3 class="list-title">#item.Name</h3>
</div>
</div>
<div class="mt-list-container list-news ext-1">
<ul>
<li class="mt-list-item">
<div class="list-icon-container">
<a href="#Url.Action("Detail", "Project", new {ID = item.ID })">
<i class="fa fa-angle-right"></i>
</a>
</div>
<div class="list-datetime bold font-red"> Sözleşme Başlangıç ve Bitiş Tarihleri </div>
<div class="list-datetime bold font-red"> #((item.SozBasTarihi ?? DateTime.Now).ToString("dd/MM/yyyy")) / #((item.SozBitisTarihi ?? DateTime.Now).ToString("dd/MM/yyyy")) </div>
<div class="list-item-content">
<div class="form-group">
<label>Nakdi Tamamlanma Oranı: %#item.NakdiTamOrani</label>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" style="width: #(item.NakdiTamOrani)%;"></div>
</div>
</div>
<div class="form-group">
<label>Fiziki Tamamlanma Oranı: %#item.FizikiTamOrani</label>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" style="width: #(item.FizikiTamOrani)%;"></div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
}
</div>
As you can see, when I click city on the map, pop-up windows is open. What I want to do is when I click on pop-up body; I want to go to the detail page of the relevant project with JavaScript. I've try with JavaScript but I failed.
My JavaScript code in ProjectListPartial.cshtml page:
<script>
$('div.ProjectPartialBody').click(function (el) {
var projectid = $(this).data('id');
$.ajax({
method: "get",
url: '#Url.Action("Detail", "Project")',
data: { projectID: projectid }
})
.done(function (msg) {
// I do not know what to write here.
});
});
</script>
try this:
<script>
//pass vale in url
function navigateURL(value) {
var url = '#Url.Action("Index", "ProductView", new {id = "_value" })';
var urlWithValue = url.replace('_value', value);
window.location.href = urlWithValue;
}
</script>

asp.net mvc loading first entries and the others - late

I'm using asp.net mvc razor
The page must show a very long list. Phonebook employees - about 500 people. Page is loading too slowly because of too many entities.
How to load first 50 entries, and later the others 450 entries - by background?
Thank you so much!
Code on page:
#model WarehouseSearch.Controllers.PhonesList
#{
string LastFirstChar = "";
}
<div id="main-content">
<div class="container">
<div class="row">
<div class="col-md-10">
<h2>Phonebook </h2>
</div>
<div class="col-md-4">
</div>
</div>
<div class="row">
<div class="col-md-8" style="border:1px solid #ddd;background-color:white">
<div class="row" style="background-color:rgba(247, 225, 181, 1);margin-bottom:1em;padding:0.5em;">
<div class="col-md-7 text-left" style="padding-left: 1em; padding-top: 0.2em; padding-right: 1em; padding-bottom: 0.3em;">
<span class="fa fa-user fa-2x blue"></span> <input type="text" name="Search" id="search_input" placeholder="search ..." class="search_input" />
</div>
<div class="col-md-3">
</div>
</div>
<ul id="phones" class="interleave">
#foreach (WarehouseSearch.GetPeoplePhonesListResult p in Model.allphones)
{
<li style="padding-top:2em;" class="row">
<div class="col-md-2">
#if (LastFirstChar != #p.FirstChar)
{
<span style="background-color:#41a7e2;color:white;position:relative;left:-4em;font-size:210%;padding:0.3em;" class="text-right"><b>#p.FirstChar</b></span>
LastFirstChar = p.FirstChar;
}
<img style="width: 85%; display: block;" src="#p.BigPhoto" /><br />
</div>
<div class="col-md-5">
<h3 class="phone smarttlink" style="margin-bottom:0.1em;margin-top:0;">#p.Family</h3>
<div>#p.FirstMiddleName</div>
<br />
<small style="color:#666">#p.Title</small>
</div>
.... some other info about people....
</li>
}
</ul>
</div>
</div>
</div>
</div>
<script>
$('#search_input').animate({
//"width": "100%",
//"padding": "4px",
"opacity": 1
}, 300, function () {
$(this).focus();
});
$(function () {
$(function () {
$('#search_input').fastLiveFilter('#phones'
, {
selector: ".phone, .phone2"
, callback: function (total) {
$('.phone').unhighlight();
searchTerm = $('#search_input').val();
if (searchTerm.length > 0) {
$('.phone').highlight(searchTerm);
}
}
, translit : true
}
);
});
});
</script>
in Controller:
:
public ActionResult List()
{
using (WarehouseSearch.sqldbDataContext sqldb = new WarehouseSearch.sqldbDataContext())
{
PhonesList pl = new PhonesList();
pl.allphones = sqldb.GetPeoplePhonesList().ToList<GetPeoplePhonesListResult>();
return View("~/Views/Home/PeoplePhones.cshtml", pl);
}
}
First I would recommend you to use an external CSS file instead of inline styling.
That way the CSS can be cached in the browser and might help you to boost the performance.
Also in a div with a class "row" you have only 12 columns,it should be like this.
<div class="row">
<div class="col-md-10">
<h2>Phonebook </h2>
</div>
<div class="col-md-2">
</div>
</div>
I would try change this Action to take the first 50
public ActionResult List()
{
using (WarehouseSearch.sqldbDataContext sqldb = new WarehouseSearch.sqldbDataContext())
{
PhonesList pl = new PhonesList();
pl.allphones = sqldb.GetPeoplePhonesList().Take(50).ToList<GetPeoplePhonesListResult>();
return View("~/Views/Home/PeoplePhones.cshtml", pl);
}
}
And later in the view after it finished to iterate over the top 50 phones
Call to another function from the controller that will retrieve the rest of the phones.
#{
((HomeController)this.ViewContext.Controller).GetLast450();
}
And iterate that, probably a partial view will be good here.

AngularJS: How to prevent "code flash" in page while loading

I have created a simple app using AngularJS. When I open the page for a second I see the screen below:
However, after the load is complete I see the loaded and styled content which is fine:
How do I prevent the flash of AngularJS code on my page ? Is this related to FOUC ?
Here is the HTML code:
<!doctype html>
<html class="no-js" lang="en" ng-app="MainApp">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Foundation | Welcome</title>
<link rel="stylesheet" href="css/foundation.css" />
<script src="js/vendor/modernizr.js"></script>
<style>
.row.full-width {
width: 100%;
margin-left: auto;
margin-right: auto;
max-width: initial;
}
</style>
</head>
<body ng-controller="MainCtrl">
<div class="off-canvas-wrap" data-offcanvas>
<div class="inner-wrap">
<nav class="tab-bar">
<section class="right-small">
<a class="right-off-canvas-toggle menu-icon" href="#"><span></span></a>
</section>
<section class="left tab-bar-section">
<h1 class="title">Salary Calculator</h1>
</section>
</nav>
<aside class="right-off-canvas-menu">
<ul class="off-canvas-list">
<li>
<label>Location</label>
</li>
<li>United Kingdom
</li>
</ul>
</aside>
<section class="main-section">
<div class="row full-width">
<div class="large-4 columns">
<ul class="tabs" data-tab>
<li class="tab-title active">Annual Salary
</li>
<li class="tab-title">Monthly Expenses
</li>
</ul>
<div class="tabs-content">
<div class="content active" id="panel1">
<div class="row">
<div class="large-12 columns">
<input ng-change="calculate()" type="text" placeholder="Salary" ng-model="salary"/>
</div>
</div>
</div>
<div class="content" id="panel2">
<div class="row">
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Rent" ng-model="rent" />
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Wireless, TV, Home Phone" ng-model="telecom"/>
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="TV License" ng-model="tv" />
</div>
</div>
<div class="row">
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Mobile Phone" ng-model="mobile"/>
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Subscription" ng-model="subscription"/>
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Electricty" ng-model="electricity" />
</div>
</div>
<div class="row">
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Food" ng-model="food"/>
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Transport" ng-model="transport" />
</div>
<div class="large-4 columns">
<input ng-change="calculate()" type="text" placeholder="Charity" ng-model="charity"/>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<input ng-change="calculate()" type="text" placeholder="Other" ng-model="other"/>
</div>
</div>
</div>
</div>
</div>
<div class="large-8 columns" ng-cloak >
<table >
<thead>
<tr>
<th width="200"></th>
<th width="250">Yearly</th>
<th width="250">Monthly</th>
<th width="250">Weekly</th>
<th width="250">Daily</th>
</tr>
</thead>
<tbody ng-repeat="val in results">
<tr>
<td>{{val.rowType}}</td>
<td>{{val.yearly}}</td>
<td>{{val.monthly}}</td>
<td>{{val.weekly}}</td>
<td>{{val.daily}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<a class="exit-off-canvas"></a>
</div>
</div>
<script src="../bower_components/angularjs/angular.js"></script>
<script src="js/app-service.js"></script>
<script src="js/app-controller.js"></script>
<script src="js/app-directives.js"></script>
<script src="js/app.js"></script>
<script src="js/vendor/jquery.js"></script>
<script src="js/foundation.min.js"></script>
<script>
$(document).foundation();
</script>
</body>
</html>
EDIT:
Please see my answer as well for an alternative solution in addition to the accepted one.
ng-cloak will help to some extent, but you can fully prevent it using ng-bind directive instead of using {{ }}.
e.g.
<td ng-bind="val.monthly"> </td>
not
<td>{{val.monthly}}</td>
It has been a long time but here is for my working solution for this one:
You need to use ng-cloak on the body tag of your html BUT the most important part is this CSS below:
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
For me I had to add this for getting ng-cloak to work. This is probably not the only solution to this problem as can be seen in other answers. Hope this helps someone.
Angular already gives you the tool to prevent this: ngCloak: https://docs.angularjs.org/api/ng/directive/ngCloak
Just put the directive on your body like <body ng-cloak> and it should work.
EDIT
The Docs also advice you to actually not put it on the body, but on smaller portions of your page - wherever you see the need. Depending on the size of your page, that is a good idea. For smaller Pages I put it on the body and never had problems.
Along with ng-cloak, you can use a resolve object in your router. This will prevent the controller from instantiating and the view from rendering until the data is there.
In the following example I am assuming you are using uiRouter. The same pattern applies for ngRouter.
Your state config:
$stateProvider
.state('yourState',{
templateUrl: 'yourTemplate.html',
controller: 'YourController as vm',
resolve: YourController.resolve
})
As you can see, you have set the resolve property of the state to a static resolve object on your controller. Now the route will not resolve until this object is resolved.
To setup resolve object, lets assume you have a service yourService that has a method getData that returns a promise. This is very important. Because we don't want the route resolved until the promise is resolved.
So your controller may look something like this.
YourController.$inject = ['yourService'];
function YourController(yourService) {
var self = this;
yourService.getData().then((data) { self.data = data});
}
This is pretty standard. You can access the data from the view with vm.data but you will see a flash of {{vm.data}}. That is, if we remove the resolve we have added to the state config.
So now we change the controller to add a static resolve object to work with the resolve we have added to the state config.
YourController.resolve = {
'yourService': 'yourService',
'data': ['yourService', function(yourService) {
return yourService.getData();
}]
}
YourController.$inject = ['data'];
function YourController(data) {
this.data = data;
}
So now we have a resolve object. The yourService will resolve as a normal service, but the data property will resolve only when the promise returned by getData() is resolved. Then this data will be passed directly into the controller using Dependancy Injection.
In reality, you probably wont need to use ng-cloak if you use resolve.
Here is a working example:
angular.module('app', ['ui.router'])
.config(['$stateProvider',
function($stateProvider) {
$stateProvider
.state('noDot', {
controller: "NoDotController",
template: "Using a old style $scope binding {{customers[0].CutomerName}}"
})
.state('noResolve', {
controller: "NoResolveController as vm",
template: "We are displaying things before the data is here {{vm.customers[0].CustomerName}}"
})
.state('withResolve', {
controller: "WithResolveController as vm",
template: "We are waiting for data before displaying anything {{vm.customers[0].CustomerName}}",
resolve: WithResolveController.resolve
})
.state('empty', {
template: ""
})
}
])
.controller('NoResolveController', NoResolveController)
.controller('NoDotController', NoDotController)
.controller('WithResolveController', WithResolveController)
.service('northwind', Northwind);
NoDotController.$inject = ['$scope', 'northwind'];
function NoDotController($scope, northwind) {
northwind.getCustomers().then(function(customers) {
$scope.customers = customers});
}
NoResolveController.$inject = ['northwind'];
function NoResolveController(northwind) {
var self = this;
northwind.getCustomers().then(function(customers) {
self.customers = customers;
});
}
WithResolveController.resolve = {
'northwind': 'northwind',
'customers': ['northwind',
function(northwind) {
return northwind.getCustomers();
}
]
}
WithResolveController.$inject = ['customers'];
function WithResolveController(customers) {
this.customers = customers;
}
Northwind.$inject = ['$timeout', '$q'];
function Northwind($timeout, $q) {
this.$q = $q;
this.$timeout = $timeout;
}
Northwind.prototype.getCustomers = function() {
var deferred = this.$q.defer();
this.$timeout(function() {
deferred.resolve([{CustomerName: "Name of Customer"}])
}, 1000);
return deferred.promise;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.13/angular-ui-router.js"></script>
<div ng-app="app">
<a ui-sref="noDot" href="#">No Dot</a>
<span> | </span>
<a ui-sref="empty" href="#">Emtpy</a>
<span> | </span>
<a ui-sref="noResolve" href="#">No Resolve</a>
<span> | </span>
<a ui-sref="empty" href="#">Emtpy</a>
<span> | </span>
<a ui-sref="withResolve" href="#">With Resolve</a>
<br>
<br>
<ui-view></ui-view>
</div>

Bootstrap Validator not working on File Input

I have a form field that should only accept a .jpg or .png image at a certain file size. The validation doesn't seem to be working(tested with invalid file types). This is what I have so far, so what is it I'm missing? I should work like it does here http://bootstrapvalidator.com/validators/file/
jsFiddle: http://jsfiddle.net/933yvfmh/3/
<div class="container-fluid">
<form id="fileupload">
<div class="row top">
<div class="col-md-4"></div>
<div class="col-md-4 logo">Image Cropper</div>
<div class="col-md-4"></div>
</div>
<div class="row">
<div class="col-md-6">
<div class="panel crop">
<div class="well">
<input type="file" mulitple name="fileupload" class="btn btn-default form-control" id="file" />
<button class="btn btn-default" id="reset">Reset</button>
<input id="renderButton" type="button" value="Render final image" class="btn btn-primary" />
</div>
<div class="panel-body">
<div id="container" class="well"></div>
</div>
</div>
</div>
<div class="col-md-6 render">
<div class="panel">
<div class="panel-body">
<div id="result_container" class="result thumbnail"></div>
</div>
</div>
</div>
</div>
</form>
</div>
//HIDE CONTROLS UNTIL IMAGE SELECTED//
$("#reset, #renderButton, .render").hide();
$("#file").click(function () {
$("#reset, #renderButton").show();
});
//ONLY SHOW RENDERED VIEW WHEN RENDER BUTTON CLICKED//
$("#renderButton").click(function () {
$(".render").fadeIn("slow").animate({
right: '50px'
});
$(".render, #result_container").show();
})
//RESET RENDER VIEW//
$("#reset").click(function () {
$(".imgly-container").empty();
});
$('#fileupload').bootstrapValidator({
live: 'enabled',
fields: {
fileupload: {
validators: {
file: {
extension: 'jpg, png',
type: 'image/jpg, image/png',
minSize: 1024 * 1024,
message: 'The selected file is not valid, or the size is not large enough!'
}
}
}
}
});
Just remove the spaces in extension and type
extension: 'jpg,png',
type: 'image/jpg,image/png',
See: http://formvalidation.io/validators/file/
Best regards,
thosimo
You are missing
notEmpty: {
message: 'This field can not be empty.'
}
So your code should be
validators: {
notEmpty: {
message: 'This field can not be empty.'
},
file: {
extension: 'jpg, png',
type: 'image/jpg, image/png',
minSize: 1024 * 1024,
message: 'The selected file is not valid, or the size is not large enough!'
}},
Hope this work.

Categories

Resources