Using Semantic UI Search with CakePHP 3 - cakephp

I'm not sure what I'm doing wrong exactly but I've been on this for hours, when it's supposed to be relatively straightforward. Here's my html;
<div class="ui search focus">
<div class="ui left icon input">
<input class="prompt" type="text" placeholder="Search GitHub" autocomplete="off">
<i class="github icon"></i>
</div>
<div class="results"></div>
</div>
And here's my script
$(document).ready(function () {
$('.ui.search')
.search({
apiSettings: {
url: '//api.github.com/search/repositories?q={query}'
},
fields: {
results : 'items',
title : 'name',
url : 'html_url'
},
minCharacters : 3
});
});
This is exactly from the examples page: https://semantic-ui.com/modules/search.html#/examples
When I try to load local data in the form of
var content = [
{ title: 'Andorra' },
{ title: 'United Arab Emirates' },
{ title: 'Afghanistan' },
{ title: 'Antigua' },
{ title: 'Anguilla' },
// etc
];
$('.ui.search')
.search({
source: content
});
It works, no problems, however loading external content like in the first snippet shows No results found and when I check the network tab in Network in Browser Dev tool, I see a 307 Internal Redirect on the request and another with a 200 Ok request which apparently gets the data from Github. Obviously I'm missing something here and will really appreciate some guidelines please. Thanks

you can try this using Url helper
url: "<?= $this->Url->build('https://api.github.com/search/repositories?q={query}', true); ?>"

Related

Angular Bootstrap UI Modal - Next/Previous

I'm relatively new to Angular, and am using it to filter a large list of products, and then that list of products has the ability to be opened in a modal where additional details are displayed.
I've seen a working example of a next/previous modal that's NOT using bootstrap UI, but have yet to see one that IS using bootstrap UI.
Here's a Plunker with a simplified working list and modal via bootstrap UI but I've been going crazy trying to figure out how to show the next/previous modal from inside the opened modal?
http://plnkr.co/edit/mRxzn8crtkaKCL8SZlQB?p=preview
var app = angular.module('sortApp', ['ui.bootstrap']);
app.controller('ModalInstanceCtrl', function ($scope, $modalInstance, feature) {
$scope.feature = feature;
$scope.ok = function (feature) {
$modalInstance.close($scope.feature);
};
});
angular.module('sortApp').controller('mainController', function ($scope, $modal, $log) {
// MODAL WINDOW
$scope.open = function (_feature) {
var modalInstance = $modal.open({
controller: "ModalInstanceCtrl",
templateUrl: 'myModalContent.html',
keyboard: true,
resolve: {
feature: function () {
return _feature;
}
}
});
//No CLUE WHAT TO DO HERE!?
$scope.showNext = function (_feature, index) {
if ((index + 1) > ($scope.allfeatures.length - 1)) {
return;
}
else {
turtle.show = false;
$scope.allfeatures[index + 1].show = true;
}
};
};
// create the list of features
$scope.allfeatures = [
//Website Widgets
{ index: 0, ID: 1, image: 'img/upload-tools.png', name: 'Upload Tools', type: 'Website Widgets', category: 'Registration, Exhibitor, Housing', description: 'Attendees can upload credentials, student verification letters, professional licenses and other documentation required to validate their registration status.' },
{ index: 1, ID: 1, image: 'img/translation.png', name: 'Website Translation', type: 'Website Widgets', category: 'Registration, Exhibitor, Housing', description: 'Microsoft Translator is used to translate your registration and housing websites with the click of one button.' },
{ index: 2, ID: 1, image: 'img/fundraising.png', name: 'Fundraising Motivator', type: 'Website Widgets', category: 'Registration, Exhibitor, Housing', description: 'Encourage your attendees to help you reach fundraising goals with visually appealing dynamically populated graphics.' },
{ index: 3, ID: 1, image: 'img/analytics.png', name: 'Google Analytics', type: 'Website Widgets', category: 'Registration, Exhibitor, Housing', description: "<h2>Know your audience</h2> <p>Google Analytics helps you analyze visitor traffic and paint a complete picture of your audience and their needs, wherever they are along the path to purchase. Giving you an edge on what your visitors need and want.</p> <h2>Trace the customer path</h2><p>Knowing where a customer is on your site, and how they got there is a critical part of finding out who they are. Tools like Traffic Sources and Visitor Flow help you track the routes people take to reach you, as well as the devices they use to get there. Armed with this valuable information an ideal user experience can be created for them.</P> <h2>Analyze important trends</h2> Utilize a tool like In-Page Analytics which lets you make a visual assessment of how visitors interact with your pages. Learn what they're looking for and what they like, then tailor all of your marketing activities for maximum impact." }
];
});
and the HTML
<body ng-app="sortApp" ng-controller="mainController">
<br>
<div class="container">
<ul class="list-group">
<li class="list-group-item" ng-repeat="feature in allfeatures">
<a ng-click="open(feature)">
<div class="card-content">
{{ feature.name }}
</div>
</a>
</li>
</ul>
</div>
<!--MODAL WINDOW-->
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3>{{ feature.name }}</h3>
</div>
<div class="modal-body">
<h5>{{ feature.category }}</h5>
<h5>{{ feature.type }}</h5>
</p>
</div>
<div class="modal-footer">
<div class="row">
<div class="col-sm-6 text-left">
<a class="previous btn btn-default btn-lg" ng-click="showPrev(t, $index)"><i class="fa fa-arrow-left"></i> Previous</a>
</div>
<div class="col-sm-6 text-right">
<a class="next btn btn-default btn-lg" ng-click="showNext(t, $index)">Next <i class="fa fa-arrow-right"></i></a>
</div>
</div>
</div>
</script>
</body>
Check this out: http://plnkr.co/edit/COFgAJ1UpZlHLEe2VOoq?p=preview
Your showPrev and showNext functions are supposed to go inside your ModalInstanceController:
app.controller('ModalInstanceCtrl', function ($scope, $modalInstance, feature) {
$scope.feature = feature;
$scope.showNext = function (feature, index) {
$modalInstance.close("next");
};
$scope.showPrev = function(feature, index) {
$modalInstance.close("prev");
};
});
The logic for this part is nearly identical to the other example, except for what you do in each case:
angular.module('sortApp').controller('mainController', function ($scope, $modal, $log) {
// MODAL WINDOW
// create the list of features
$scope.allfeatures = [
//Website Widgets
{ index: 0, ID: 1, image: 'img/upload-tools.png', name: 'Upload Tools', type: 'Website Widgets', category: 'Registration, Exhibitor, Housing', description: 'Attendees can upload credentials, student verification letters, professional licenses and other documentation required to validate their registration status.' },
{ index: 1, ID: 1, image: 'img/translation.png', name: 'Website Translation', type: 'Website Widgets', category: 'Registration, Exhibitor, Housing', description: 'Microsoft Translator is used to translate your registration and housing websites with the click of one button.' },
{ index: 2, ID: 1, image: 'img/fundraising.png', name: 'Fundraising Motivator', type: 'Website Widgets', category: 'Registration, Exhibitor, Housing', description: 'Encourage your attendees to help you reach fundraising goals with visually appealing dynamically populated graphics.' },
{ index: 3, ID: 1, image: 'img/analytics.png', name: 'Google Analytics', type: 'Website Widgets', category: 'Registration, Exhibitor, Housing', description: "<h2>Know your audience</h2> <p>Google Analytics helps you analyze visitor traffic and paint a complete picture of your audience and their needs, wherever they are along the path to purchase. Giving you an edge on what your visitors need and want.</p> <h2>Trace the customer path</h2><p>Knowing where a customer is on your site, and how they got there is a critical part of finding out who they are. Tools like Traffic Sources and Visitor Flow help you track the routes people take to reach you, as well as the devices they use to get there. Armed with this valuable information an ideal user experience can be created for them.</P> <h2>Analyze important trends</h2> Utilize a tool like In-Page Analytics which lets you make a visual assessment of how visitors interact with your pages. Learn what they're looking for and what they like, then tailor all of your marketing activities for maximum impact." }
];
$scope.open = function (_feature, index) {
var modalInstance = $modal.open({
controller: "ModalInstanceCtrl",
templateUrl: 'myModalContent.html',
keyboard: true,
resolve: {
feature: function () {
return _feature;
}
}
});
modalInstance.result.then(function(result) {
if (result == "next") {
if(index +1 < $scope.allfeatures.length) {
$scope.open($scope.allfeatures[index+1], index+1);
}
}
else {
if(index -1 >= 0) {
$scope.open($scope.allfeatures[index-1], index-1);
}
}
});
};

Storing array data from angularjs Form using MEAN stack

I am using MEAN stack. while creating a new article i would like to save array data. below code has the section deal which needs to be an array of data, for which i am unable to store array data. how do i modify my html partial and angularJS Controller so that i can store data like below for deal
{
"_id": "565d8a3a0ede9823aca797e9",
"user": {
"_id": "564ef3eaebf280b0abcc4876",
"displayName": "Table 2"
},
"__v": 0,
"deal": ["Special","Holiday"],
"name": "Idli",
"created": "2015-12-01T11:53:30.759Z"
}
My NodeJS Server Model
var FoodSchema = new Schema({
created: {
type: Date,
default: Date.now
},
name: {
type: String,
default: '',
required: 'Please fill Food name',
trim: true
},
deal: [{
type: String,
default: '',
trim: true
}],
user: {
type: Schema.ObjectId,
ref: 'User'
}
});
my AngularJS controller
$scope.create = function (isValid) {
$scope.error = null;
if (!isValid) {
$scope.$broadcast('show-errors-check-validity', 'foodForm');
return false;
}
// Create new Food object
var food = new Foods({
name: this.name,
deal: this.deal,
// Redirect after save
food.$save(function (response) {
$location.path('foods/' + response._id);
// Clear form fields
$scope.name = '';
$scope.deal = '';
}, function (errorResponse) {
$scope.error = errorResponse.data.message;
});
};
HTML Partial
<section ng-controller="FoodsController">
<div layout="row" layout-wrap class="create-food">
<form name="foodForm" ng-submit="create(foodForm.$valid)" novalidate>
<div class="col-md-12">
<md-input-container flex="">
<label >Food Name</label>
<input type="text" data-ng-model="name" id="name" required>
</md-input-container>
</div>
<div class="col-md-6">
<md-input-container class="">
<label class="" for="deal">Deal</label>
<input type="text" data-ng-model="deal" id="deal" required>
</md-input-container>
</div>
<md-button type="submit">Create Food</md-button>
</form>
</div>
</section>
if you want to store data on your browser you can use the new html5 feature localStorage(key,value) you put some key for getting and the json like value.
This is not just for the sesion !
Well, I see that you already updated your mongoose model schema and made some updates in the frontend but what's the current state of your server API? Do you have any endpoints defined for the requests?
In other words (using the articles example of MEAN.js):
var articlesPolicy = require('../policies/articles.server.policy'),
articles = require('../controllers/articles.server.controller');
module.exports = function (app) {
// Articles collection routes
app.route('/api/articles').all(articlesPolicy.isAllowed)
.get(articles.list)
.post(articles.create);
// Single article routes
app.route('/api/articles/:articleId').all(articlesPolicy.isAllowed)
.get(articles.read)
.put(articles.update)
.delete(articles.delete);
// Finish by binding the article middleware
app.param('articleId', articles.articleByID);
};
Do you already have a similar setup for Food?
Once you have your routes setup you should then verify the server controllers logic and see if the data is being handled correctly and save into mongodb.
Edit to explain the workflow of saving data to mongodb in MEAN.js:
The database is only accessible from the server for security reasons. You cant access mongodb directly from angularjs. The process is: angular passes the data to expressjs via a request (for example: GET, POST, PUT, DELETE). Then in the server you should be able to capture the requests by defining your route endpoints. In those route endpoints you can specify route middlewares (i.e., server controllers) that will then use mongoose to interact with mongodb.

Angular Grouping Directive starting point

I'am trying to create a grouping and filtering mechanism with several predefined filters. I have a collection of undefined rules and some predefined grouping actions, for example "relativeDate" (today, tomorrow, yesterday, this week, ...), "boolean" or . The set of actions should be expandable.
I've managed to get this working in a controller. But I want to outsource this into a directive to get this working with other object collections. The Problem is: I need to specify the template of the list dynamically.
Imagine the following collections:
$scope.memosReceived = [
{ id: 1, from: 'Henry Ford', title: 'Want your Model T?', received: '2015-05-04T12:30:00', read: true },
{ id: 2, from: 'Oliver Newton', title: 'Look at this!', received: '2015-06-15T08:00:00', read: true }
...
];
$scope.memosSent = [
{ id: 1, to: 'Henry Ford', title: 'That is an old car', sent: '2015-05-04T12:35:21', read: true },
{ id: 2, to: 'Oliver Newton', title: 'Stop Spam', sent: '2015-06-15T08:01:47', read: false }
...
];
Now the markup should be like the following:
<div ng-controller="controller">
<h2>Received</h2>
<grouped-list ng-model="memosReceived" item-var="received" grouping-options="groupingReceived">
<h2>{{ received.title }} <sub>by {{ received.from }}</h2>
</grouped-list>
<h2>Sent</h2>
<grouped-list ng-model="memosSent" item-var="sent" grouping-options="groupingSent">
<h2>{{ sent.title }} <sub>to {{ sent.to }}</h2>
</grouped-list>
</div>
Options could be like:
$scope.groupingReceived = [
{ modelKey: 'received', action: 'relativeDate', options: { [.. passed to grouping action, like value->name mapping ..] },
{ modelKey: 'read', action: 'boolean', options: { [...] } }];
$scope.groupingSent = [
{ modelKey: 'sent', action: 'relativeDate', options: { [.. passed to grouping action, like value->name mapping ..] },
{ modelKey: 'read', action: 'boolean', options: { [...] } }];
The rendered HTML should look like this "PseudoHtml":
<div ng-controller="controller">
<h2>Received</h2>
<div class="grouped-list">
<div class="filter-section">
<button ng-click="openFilters = !openFilters>Open Filters</button>
<div class="filter-options" ng-hide="!openFilters">
<h4>Group by</h4>
[selectbox given group actions] [selectbox sort ascending or descending]
<h4>Filter by</h4>
[build filters by similar to group actions given filter actions]
</div>
</div>
<div class="group">
<div class="group-header">
<h3>Yesterday</h3>
</div>
<ul class="group-list">
<li ng-repeat="received in ngModel | customFilters">
<!-- something like transclusion starts here -->
<h2>{{ received.title }} <sub>by {{ received.from }}</h2>
<!-- something like transclusion ends here -->
</li>
</ul>
</div>
<div class="group">
<div class="group-header">
<h3>Last Week</h3>
</div>
<ul class="group-list">
<li ng-repeat="received in ngModel | customFilters">
<!-- something like transclusion starts here -->
<h2>{{ received.title }} <sub>by {{ received.from }}</h2>
<!-- something like transclusion ends here -->
</li>
</ul>
</div>
</div>
<h2>Sent</h2>
<div class="grouped-list">
[... same like above ...]
</div>
</div>
I am really struggeling how to achieve this behavior, where to store the several parts of the logic (e.g. the grouping actions, the custom filters) and how to transclude this correctly.
Maybe someone can give me a good starting point for that.
You could create a custom filter and call it from the controller of your directive.
Inside of this filter you can decide which filter action should be triggered by passing parameters to the filter.
I would call it from the controller instead of the template because there you can easier chain your filters.
Please have a look at the demo below or in this jsfiddle.
During adding my code to SO I've detected a bug (not displaying the item) in my code with a newer AngularJS version. Not sure what it is but with 1.2.1 it's working.
I'll check this later. Seems like a scoping issue.
angular.module('demoApp', [])
.filter('aw-group', function($filter) {
var filterMethods = {
relativeDate: function(input, action) {
console.log('relative date called', input);
return input; // do the translation to relative date here
},
filterByNumber: function(input, action, options) {
// if you need mor parameters
return $filter('filter')(input, options.number);
},
otherFilter: {
}
};
return function(input, action, options) {
return filterMethods[action](input, action, options);
};
})
.directive('groupedList', function () {
return {
restrict: 'E',
scope: {
model: '=',
itemVar: '=',
filter: '='
},
transclude: true,
template: '<ul><li ng-repeat="item in filteredModel" ng-transclude>'+
'</li></ul>',
controller: function($scope, $filter) {
//console.log($scope.filter);
$scope.filteredModel = $filter('aw-group')($scope.model, 'filterByNumber', { number: 2 }); // passing action from $scope.filter.action as second parameter, third is an options object
}
};
})
.controller('mainController', function () {
this.data = [{
title: 'Test1',
from: 'tester1'
}, {
title: 'Test2',
from: 'tester1'
}, {
title: 'Test3',
from: 'tester1'
}, ];
this.groupingReceived = [{
modelKey: 'received',
action: 'relativeDate',
options: {},
modelKey: 'read',
action: 'boolean',
options: {}
}];
this.memosReceived = [{
id: 1,
from: 'Henry Ford',
title: 'Want your Model T?',
received: '2015-05-04T12:30:00',
read: true
}, {
id: 2,
from: 'Oliver Newton',
title: 'Look at this!',
received: '2015-06-15T08:00:00',
read: true
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<div ng-app="demoApp" ng-controller="mainController as ctrl">
<grouped-list model="ctrl.data" item-var="received" filter="ctrl.groupingReceived">
<h2>{{item.title}}<sub>{{item.from}}</sub></h2>
</grouped-list>
</div>

Meteor mobile web app touch support

I have a Meteor app that's having problems on mobile browsers. I'm using the autocomplete package (meteor-autocomplete), but I can't select the autocomplete options that drop down using touch. It works fine on the desktop browser when I click on the options. What's the problem? Also, how can I modify the app for mobile browsers (presentation, etc.).
Thanks
Edit:
Here's the html template code:
<template name="form">
{{> inputAutocomplete settings=settings id="food" class="form-control" name="food" placeholder="e.g. Chicken Pot Pie"}}
</template>
And here's Template.form.helpers:
Template.form.helpers({
settings: function() {
return {
position: "bottom",
limit: 5,
rules:
[
{
collection: Records,
field: 'food',
matchAll: true,
template: Template.foodFill
}
]
};
},
records: function() {
return Records.find().fetch();
}
});
And the Records collection holds all the entries to be used by autocomplete.

load new view after the loginin extjs 4 mvc

I have a login view created in extjs 4 and the data is fetched from mysql.
What my issue is that i am not able to redirect my page after the sucessfull login.
My code to redirect is.
onLoginSuccess : function(response, opts)
{
//Received response from the server
response = Ext.decode(response.responseText);
if(response.success)
{
var redirect = 'index';
window.location = redirect;
}
else
{
Ext.MessageBox.alert('Login failed', response.message);
}
}
There are two ways to approach this:
Login as a separate page
This is the recommended way, for being faster and more secure.
Have an index.php page, that checks whether the user has logged in or not.
If the user is logged in, you should simply require your actual system index file, which includes the ExtJs headers.
If the user is not logged in, you should require a login.php file that shows the actual login screen. This page may, or may not load the ExtJs library (since there's very little on this page, I'd assume you won't need the ExtJs files here).
So for example, this is my index.php:
<?php
require_once('common/include/User.php');
if ( SessionUser()->IsLoggedIn() )
{
// chdir is simply to keep the correct paths when compiling the app.
// It works for php, but for html/css links you should use the base tag
// in your php/html file: <base href="app/"/>
chdir('app');
require_once('app/index.php');
} else {
require_once('login.php');
}
?>
Then app/index.php is the actual index file that loads your app scripts and ExtJs lib.
login.php is just a rather simple login form:
<?php
// Index file for logged out users (guests)
$iUserName = isset( $_POST['username'] ) ? $_POST['username'] : '';
$iLoginErrorTxt = '';
if ( isset( $_POST['username'] ) )
{
require_once('common/include/User.php');
$iLoginError = SessionUser()->Authenticate( $_POST['username'], $_POST['password'] );
if ( $iLoginError['success'] )
{
// Login successful - reload the page.
header( "Location: " . $_SERVER['PHP_SELF'] );
exit();
} else {
// Login failed - present an error.
$iLoginErrorTxt = $iLoginError['error'];
}
}
?>
<html>
<head>
<title>My System</title>
</head>
<body>
<form class="login-form" action="<?=$_SERVER['PHP_SELF']?>" enctype="application/x-www-form-urlencoded" method="post">
<input name="username" size="25" type="text" value="<?=$iUserName?>" value spellcheck="false" placeholder="User Name"/>
<input name="password" size="25" type="password" value spellcheck="false" placeholder="Password"/>
<div class="error-message"><?=$iLoginErrorTxt?></div>
<input name="submit" type="submit" value="Login" />
</form>
</body>
</html>
Login from within the ExtJs app
This method is not highly recommended as you need the load the whole ExtJs framework and very possibly your application scripts, before the user even authenticated.
A possible implementation will involve having a container panel, which only displays a panel at a time, being either the login page, or the actual application page.
The app.js might include this code:
refs:
[{
ref: 'contentPanel',
selector: 'viewport > #contentPanel'
}],
controllers: [
'MainMenu'
],
launch: function() {
// Enable quicktips
Ext.QuickTips.init();
// Create the viewport
Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [
{
xtype: 'panel',
id: 'contentPanel',
layout: 'card',
dockedItems: [{
xtype: 'mainmenu',
dock: 'top'
}]
}
]
});
},
Then you can do:
var iContentPanel = this.getContentPanel();
iContentPanel.getLayout().setActiveItem( iPage );
Where iPage is whatever page (panel) you wish to display.
There are obviously ways to improve how this works, for example, by dynamically loading controllers; but that's a story for a different question I believe.
Regardless, I would strongly suggest you consider the first method.
You could handle logging in by simply overlaying the whole app with a login window, like here:
http://blogapp.banchaproject.org/app.html
The code can be found here, especially the this controller will be of interest for you:
https://github.com/Bancha/BanchaBlogApp/blob/master/webroot/app/controller/Authentification.js

Resources