I am using Algolia in my web system and I really like this service. The only thing on which I am stuck is I want to show star rating of items, you can see picture attached below for more clarification.
I don't want rating widget. I have an attribute called rating that has float values like 3.54 etc. I am using Laravel 5.4
Image : https://img42.com/Xad0J
Algolia's Hits Widget
search.addWidget(
data = instantsearch.widgets.hits({
container: '#hits-container',
hitsPerPage: 10,
templates: {
item: function(data) {
return '<div class="row well_our well-sm_our"> <div class="col-md-3"> <img class="img-responsive" src="'+data.pic_path+'"> </div> <div class="col-md-6"> <div class="rest-list-heading">'+data.name+'</div> <div class="rest-list-para text-justify">'+data.description+'</div> </div> <div class="col-md-3 rest-coulmn-3"> <div title="Rating : rating" id="rating'+data.id+'"></div> <input type="hidden" id="ratingOfRest'+data.id+'" value="rating"> <div class="rest-list-para1" align="center">'+data.reviews+' <input type="hidden" id="restID'+data.id+'" value="id"></div> <div class="dotted-btn-rest" align="center"> View Menu </div> </div> </div>';
},
}
})
);
Laravel Blade:
<div id="hits-container"></div>
In order to do that you need to implement two things. One is a transformData, that will let you process your floats into elements that can be used in the the template.
You can find an example for the transformData of a star rating here. The other is the template. You can find the star rating template a little above the transform data.
Related
When a user creates a product, I want that product to be broadcasted to all other users and dynamically added to their screens. So far the broadcast aspect works amazingly.
But how can I dynamically add in this '.product' class, as well as all of a nested divs in an easy way? At the moment the only thing I can think of is copying and pasting all of it's divs in a jquery variable and adding it that way- there must be an easier way.
Here is where products are first loaded in when the page loads
<div class="product" id="{{$product->id}}">
<div class="product-image"><img src="/imgs/products/{{$product->type_id}}.png"></div>
<div class="product-content">
<div class="product-title" id="product-title">
{{ strtoupper(\App\ProductType::where('id', $product->type_id)->first()->name)}}
</div>
<div class="product-price">PRICE PER UNIT: <div class="price-value" id="price">{{$product->price}}</div> EXENS</div>
<br/>
QUANTITY: <div class="quantity-value" id="quantity">{{$product->quantity_available}}</div>
#if(strpos(\App\Group::where('id', $player->group_id)->first()->options, "\"showName\":true") !== false)
<br/>
SELLER: <div class="seller" id="seller">{{\App\User::where('id',$product->seller_id)->first()->name}}</div>
#endif
<br/>
PRICE: <div class="total-price" id="total-price">{{$product->price * $product->quantity_available}}</div>
<form class="buy-product-form" action="/UoE/buy-product/{{$product->id}}" method="POST">
{{csrf_field()}}
<button class="pull-right btn btn-primary">BUY NOW</button>
</form>
</div>
</div>
When the event is received the only way I can think of doing it as:
var productToAdd="<div class='buy-product-form'><div id='price'></div> " +
"" +
"" + //insert a massive string here containing all the other aforementioned sub-divs
"" + //And populate with json data
"" +
"</div>";
$('.content').append(productToAdd);
My solution was to take the entire code posted in the question and do make it as a one big HTML tag. That way my JS function can append the page with a HTML product div and it will already be bound with the necessary event listeners.
I'm trying to insert modal window html code dynamically upon user click on which item otherwise i load all of the items' modal window code in the html. I also have some inputs in the modal window loading from Flask/Sql and i want to let user update any of them so i need to send data back to python on submit button clicked. But right now because of i have too many modal windows (even though they have separate ids) i couldn't find a way to achieve this
Here is my code:
routes.py
#app.route('/viewApart', methods=['GET', 'POST'])
def viewApart():
apts = []
getApts = db.engine.execute("SELECT * FROM apartments")
for a in getApts:
apts.append((a))
rooms = []
getRooms = db.engine.execute("SELECT * FROM rooms")
for r in getRooms:
rooms.append((r))
return render_template('apartments.html', title=_('Apartments'), apts=apts, rooms=rooms)
apartments.html
....
<section class="container">
<div class="row">
.. below some gallery code to show individual items from apts ..
{% for apt in apts %}
<div class="col-md-3">
<a href="javascript:void(0);" class="widget__v2 apt-widget rounded-corners box-shadow__v1 white" data-anchor="modalwindow" data-target="edit-apartment{{ apt[0] }}" id="apt{{ apt[0] }}">
<div class="widget-header">
<figure class="image h-180">
<img src="{{url_for('static', filename='_assets/img/apt/{{ apt[0] }}.jpg')}}" alt="" class="image__scaledown">
</figure>
.. below model window ..
<div id="edit-apartment{{ apt[0] }}" class="modal large">
<div class="modal-wrapper">
<div class="modal-inner">
<div class="modal-header">
<h3 class="title">{{ _('Edit Apartment') }}</h3>
</div>
<div class="modal-content">
<div class="row medium-gutter">
<div class="col-md-6">
<div class="row medium-gutter">
<div class="col-md-8">
<div class="form-group">
<div class="form-group-title clearfix">
<label for="apt_display_name">{{ _('Display Name') }}</label>
<div class="lh-24 text__default-grey pull-right" data-tooltip="true" data-tooltip-direction="up" data-multiline="true"
data-content="..">
<i class="icofont-question-circle"></i>
</div>
</div>
<input id="apt_display_name" type="text" class="form-control" value="{{ apt[1] }}">
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="apt_number">{{ _('Apt. Number') }}</label>
<input id="apt_number" type="text" class="form-control" value="{{ apt[2] }}">
</div>
</div>
</div>
.. and so on...
.. and submit button ..
{{ _('Save Changes') }}
</div>
</section>
Right now even with multiple model windows, i can display the current data in modal window, so what i want to achieve this upon clicking on btnSubmit button i need to send all input values back to python so i can update my sql or insert new one. Please let me know if more code is needed..
Thanks
If I am understanding your question correctly - a skeleton version of your page would be something like this
<!DOCTYPE html>
<html>
<body>
<p>INTRODUCING MY AWESOME SITE AND 2 DIVS YOU CAN CLICK</p>
<div id="apt_1_modal">
<input id="apt_1_text"></input>
<a onclick="myFunction(event)">Submit</a>
</div>
<div id="apt_2_modal">
<input id="apt_2_text"></input>
<a onclick="myFunction(event)">Submit</a>
</div>
</body>
</html>
You will need JavaScript to handle the user interaction - the script would look something like this. You can either append this script directly to your render_template output or you can append it as a file.
The script will do 2 things - first capture what your user is inputting and second, send that data over to flask
<script>
function myFunction(e) {
//FIRST WE CAPTURE THE VALUE THAT THE USER INPUTS
let userInput = {toSend: e.currentTarget.previousElementSibling.value}
//THEN WE SEND IT TO THE FLASK BACKEND USING AJAX (Fetch API)
fetch("/api/path/to/flask/route", {
method: 'POST',
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(userInput)
}
</script>
Now you need a function that can handle the userInput data
Backend
from flask import Flask, request #import main Flask class and request object
#app.route('/api/path/to/flask/route', methods=['POST'])
def capture_userinput():
req_data = request.get_json()
recd_data = req_data['toSend']
your_code_to_push_data_to_db(recd_data) #Depends on your ORM/DB
I hope I have given you an idea of how to go about - You will most certainly have to change the way to capture userInput, tweak the fetch call and send/capture additional data in your flask api.
I am making a simple sports goods shopping app in AngularJs.
I am in a situation where I have three nested ng-repeats.
First loop: Get the brand name. I have written angularjs service that calls the rest endpoint to fetch the lists of brands (Adidas, Yonex, Stiga, etc). I am calling this service as soon as the page(controller) gets loaded.
Second loop: For each brand, I want to display the category of products they are offering. Inside this loop, I want to execute a function/service that will take the brand name as input and get all the categories for the brand. For this, I also have an angularjs service that calls the rest endpoint to fetch the list of categories for a given brand name.
Third loop: For each brand and category, I want to display the products in that category. Inside this loop, I want to execute a function that will take the brand name and category as input and get all the products in that category. I an angularjs service call which will call the rest endpoint to fetch the products given the brand name and category.
Sample data set:
Adidas
-----T-Shirts
----------V-Neck
----------RoundNeck
-----Shoes
----------Sports Shoes
----------LifeStyle Shoes
Yonex
-----Badminton Racquet
----------Cabonex
----------Nanospeed
-----Shuttlecocks
----------Plastic
----------Feather
Stiga
-----Paddle
----------Procarbon
----------Semi-carbon
-----Ping Pong Balls
----------Light Weight
----------Heavy Weight
Please note that because of some constraints I cannot have a domain object on the REST side to mimic the data structure shown above.
I want to display the above data in a tree-like fashion (something on the same lines as shown above possibly with expand/collapse options).
Below are the code snippets.
CONTROLLER:
(function () {
'use strict';
angular.module('SportsShoppingApp.controllers').controller('sportsController', ['sportsService', '$scope', function (sportsService, $scope) {
$scope.brands = [];
$scope.categories = [];
$scope.products = {};
$scope.getBrands = function () {
sportsService.getBrands()
.then(loadBrands, serviceError);
};
var loadBrands = function(response) {
$scope.brands= response.data;
};
$scope.getCategories = function(brand) {
sportsService.getCategories(brand)
.then(loadCategories, serviceError);
};
var loadCategories = function (response) {
$scope.categories = response.data;
};
$scope.getProducts = function(brand, category) {
sportsService.getProducts(brand, category)
.then(loadProducts, serviceError);
};
var loadProducts = function (response) {
$scope.products = response.data;
};
var serviceError = function (errorMsg) {
console.log(errorMsg);
};
$scope.getBrands();
}]);
}());
HTML:
<div class="well">
<div class="row">
<div id="sportsHeader" class="col-md-3">
<div ng-repeat="brand in brands.data">
<div class="row">
<div class="col-md-9">{{brand}}</div>
</div>
<div ng-repeat="category in categories.data" ng-init="getCategories(brand)">
<div class="row">
<div class="col-md-9">{{category}}</div>
</div>
<div ng-repeat="product in products.data" ng-init="getProducts(brand, category)">
<div class="row">
<div class="col-md-9">{{product}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
When I use the above HTML, only the brand names are displayed on the UI. The categories and their corresponding products are not displayed. I know that there is some overlapping that is happening. I am not sure if I am doing it the right way. I might be completely wrong with my approach. I am new to AngularJS. I want to know how to loop in nested ng-repeat so that each ng-repeat could call an angularjs service and also I want to display the data in the tree fashion as shown above. Can someone help me here?
I think that the ng-inits have to be placed on separate tags to the ng-repeats:
<div class="well">
<div class="row">
<div id="sportsHeader" class="col-md-3">
<div ng-repeat="brand in brands.data">
<div class="row">
<div class="col-md-9">{{brand}}</div>
</div>
<div ng-init="getCategories(brand)">
<div ng-repeat="category in categories.data">
<div class="row">
<div class="col-md-9">{{category}}</div>
</div>
<div ng-init="getProducts(brand, category)">
<div ng-repeat="product in products.data">
<div class="row">
<div class="col-md-9">{{product}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
You might have to juggle your bootstrap classes around also, moving ng-init is only to fix the angular part.
Move the ng-init directives outside of the ng-repeat to which they provide data.
<div class="well">
<div class="row">
<div id="sportsHeader" class="col-md-3">
<!-- MOVE init of categories here -->
<div ng-repeat="brand in brands.data" ng-init="getCategories(brand)">
<div class="row">
<div class="col-md-9">{{brand}}</div>
</div>
<!-- MOVE init of products here -->
<div ng-repeat="category in categories.data" ng-init="getProducts(brand, category)">
<div class="row">
<div class="col-md-9">{{category}}</div>
</div>
<div ng-repeat="product in products.data">
<div class="row">
<div class="col-md-9">{{product}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
The ng-init directive has a priority of 450; the ng-repeat, priority 1000. This means that when they are on the same element ng-init executes after the ng-repeat directive. The ng-repeat for categories.data won't execute its ng-init until it has a category. Thus its ng-init can't be used to populate the categories array.
Quick question. Is my approach correct ?
The approach works but it violates the Zen of Angular and the principles of an MV* Model View Whatever framework.
The model is the Single Source of Truth
Because the view is just a projection of the model, the controller is completely separated from the view and unaware of it. This makes testing a snap because it is easy to test your controller in isolation without the view and the related DOM/browser dependency.
--AngularJS Developer Guide -- Data-Binding
Having the ng-repeat and ng-init directives build the model creates a dependency that makes testing and debugging difficult. (As witnessed by this question.)
My advice is to learn how to build the model by chaining promises and using $q.all.
It's my first time when I use mustache.js and need some help, please.
Doing a html template builder and I am trying to grab data from JSON and HTML files, than show them into my page.
So I am using this script to get Default theme from JSON than to get the HTML:
$.getJSON('templates.json', function(json){
$.each(json, function(theme, val){
if(theme == 'Default'){
template.load('templates/'+val.url+'/template.html', function(response, status, xhr){
$(this).html(Mustache.render($(this).html(), {
tabs:val.tabs
}));
});
}
});
});
JSON:
{
"Default" : {
"url":"default",
"logo": "YOUR LOGO HERE",
"phone": "+1234567890",
"tabs": [
"About Us",
"Delivery",
"Payment",
"Shipping",
"Contact Us"
]
}
}
HTML:
{{#tabs.length}}
<div id="tabs">
{{#tabs}}
<input class="state" type="radio" title="tab1" name="tabs-state" id="tab1" checked />
{{/tabs}}
<div class="tabs flex-tabs">
{{#tabs}}
<label for="tab1" id="tab1-label" class="tab">{{.}}</label>
{{/tabs}}
{{#tabs}}
<div id="tab1-panel" class="panel active">[[{{.}}]]</div>
{{#tabs}}
</div>
</div>
{{/tabs.length}}
I just can't display the tabs. First time I tried with javascript to convert json into html, but Mustache was showing text instead of html. Now I am trying with conditions in html with no luck.
I also need to add numbers to each item, eg: "tab1", "tab2".. - is this {{#index}} good for that?
How can I add checked only for first items?
Also not sure if {{.}} this is displaying the name of my tab..
You've almost got this nailed, although have slightly misunderstood how to write the mustacheJS view. It's even simpler than you thought! See below. I've simplified the example, so you understand the concept.
Some explanation for below:
{{#Default}}{/Default}} represents looping over an object literal
{{#tabs}}{{/tabs}} presents looping over the object that exists within {{#Defaults}}.
{{.}} displays the entire contents of the object. If this was a complex object, it would be rendered as [object][object]. If you ever encounter this, you must name the object explicitly in your view.
<div class="tabs">
{{#Default}}
{{#tabs}}
<input class="state" type="radio" title="Tab1" name="tabs-state" checked/>
<div class=tabs flex-tabs>
{{.}}
</div>
{{/tabs}}
{{/Default}}
</div>
View Produced
<div class="tabs">
<div class=tabs flex-tabs>
About Us
</div>
<div class=tabs flex-tabs>
Delivery
</div>
<div class=tabs flex-tabs>
Payment
</div>
<div class=tabs flex-tabs>
Shipping
</div>
<div class=tabs flex-tabs>
Contact Us
</div>
</div>
Hello I am new to angular js , I need some help that i have one edit form in angular js when user click on edit it redirect to edit form but i am getting some issues that my json result look like :
[{"0":"3",
"1":"The only people for me are the mad ones",
"2":"“The only people for me are the mad ones, the ones who are mad to live, mad to talk, mad to be saved, desirous of everything at the same time, the ones who never yawn or say a commonplace thing, but burn, burn, burn like fabulous yellow roman candles exploding like spiders across the stars.”",
"3":"2015-05-08 13:01:58",
"id":"3","title":"The only people for me are the mad ones",
"description":"“The only people for me are the mad ones, the ones who are mad to live, mad to talk, mad to be saved, desirous of everything at the same time, the ones who never yawn or say a commonplace thing, but burn, burn, burn like fabulous yellow roman candles exploding like spiders across the stars.”",
"created_on":"2015-05-08 13:01:58"
}]
I want to know how to print my title , description in view.
Here is my controller file: where i get the data from database:
var myApp = angular.module("blogapp",[]);
myApp.config(['$routeProvider',function($routeProvider){
$routeProvider
.when('/home',{
templateUrl:'home.html',
controller:'blogcontroller'
})
.when('/list',{
templateUrl:'list.html',
controller:'blogcontroller'
})
.when('/add',{
templateUrl:'add.html',
controller:'addcontroller'
})
.when('/edit/:Blogid',{
templateUrl:'edit.html',
controller:'editcontroller'
})
.otherwise({
redirectTo:'/home'
});
}]);
myApp.controller('blogcontroller',function ($scope,$http){
$http({method: 'GET' , url: 'getallblog.php'}).success(function(data){
$scope.allblog = data;
console.log(data);
});
// DELETE blog HERE
$scope.removeRow= function(id){
$http.post("removeblog.php",{'id' : id}).success(function(data,status,headers,config){
window.location='index.html';
console.log("Deleted Successfully");
});
};
// delete blog code ends here
});
myApp.controller('addcontroller',function ($scope,$http){
/// New Post Here
$scope.new_post =function(){
$http.post("addblog.php" ,{'title' : $scope.title ,'description' : $scope.description }).success(function(data,status,headers,config){
window.location='index.html';
console.log("inserted Successfully");
});
};
// New Post ends Here
});
myApp.controller('editcontroller',function ($scope,$http,$routeParams){
$scope.Blogid = $routeParams.Blogid;
$http.post("getblog.php",{'id' : $scope.Blogid}).success(function(data){
$scope.editit = data; /// here i get the resuly want to pass it t view
console.log(data);
});
});
My edit html form : edit.html
<!-- Page Content -->
<div class="container">
<div class="row">
<!-- Blog Entries Column -->
<div class="col-md-6">
<h1 class="page-header">
Angular Blog
</h1>
<div >
<form class="form-signin">
<h2 class="form-signin-heading">Modify // want to print title here </h2>
<div class="row">
<div class="col-md-12">
<label for="posttitle" class="sr-only">Email address</label>
<input type="text" id="posttitle" class="form-control" ng-model="{{title}}" required="" value=""><br>
<span>Title : // want to print title here</span>
</div>
</div>
<br>
<div class="row">
<div class="col-md-12">
<label for="postdetails" class="sr-only">Password</label>
<textarea id="postdetails" class="form-control" ng-model="description" required=""></textarea>
<br>
<span>Blog Description: // want to print description here</span>
</div>
</div>
<br>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<button class="btn btn-lg btn-primary btn-block" type="button" ng-click="edit_post()" name="editblog">Modify Now</button>
</div>
<div class="col-md-3"></div>
</div>
</form>
</div>
</div>
<div class="col-md-2"></div>
<!-- Blog Sidebar Widgets Column -->
<div ng-include="'includes/sidebar.html'">
</div>
</div>
<!-- /.row -->
</div>
<!-- /.container -->
to print your title, you first need to replace this line in JS:
$scope.allblog = data;
with
$scope.allblog = data[0];
Now, you can write in HTML the following statement:
{{allblog.title}}
Something like this:
<span>Blog Description: {{allblog.description}}</span>
Or
<span>Blog Description: <span ng-bind-html ="allblog.description"></span></span>
if your allblog is an array use allblog[0]