Create a Cookie after an jQuery AJAX request? - javascript

My script is a simple like and dislike buttons (called reactions). It works well but now I want to have a quick cookie created if the vote went through so people can't vote for this particular comment ever again (ie. 1 year.. or when they remove their cookies.)
The entire function works but I am confused on how to add the cookie for each specific comment they have reacted to?
(function( $ ) {
'use strict';
$( document ).ready(function() {
$(document).on('click', '.enco-reaction', function(e){
var data = {
'action': 'enco_reaction',
'reaction': $(this).data('reaction'),
'comment': $(this).data('id')
};
$.post(
ajax_object.ajax_url,
data,
function( obj ) {
if( obj.error ) {
alert( obj.error );
} else {
$('#enco-reaction-' + obj.reaction + '-' + obj.comment + ' .enco-reaction-count' ).html( obj.value );
}
},
'json'
);
});
});
})( jQuery );

Best not to use cookies (I would recommend local storage over cookies for storing data as you can store JSON data better and larger) as it's more used for temporary data.
But for whatever reason you don't want to.
I'd store data in a JSON Object with a user identifier (however you wish to identifier users from each other) and a list of comments id's.
{
"users": {
"user_ids": {
"123": [
"111",
"222",
"333"
],
"456": [
"111",
"222",
"333"
]
}
}
}
and just JSON.stringify() before storing it in either cookies or local storage.

as per people's recommendations, I've opted for a simple table in my database and I log ip, comment_id, date, etc. and then I just retrieve the last date for a given IP and check.
thanks!

Related

How to filter search input to show correct autocomplete in JQUERY?

I have a search input where my autocomplete shows but for some reason it the results are not being filtered - can anyone tell or show me a way to filter results to show the correct autocomplete prior in my code below.. Below is the json format and the html code updated. Thanks for the help.
Here is my code
$( function() {
var cache = {};
$( "#searchTextField" ).autocomplete({
minLength: 2,
source: function( request, response ) {
var term = request.term;
if ( term in cache ) {
response( cache[ term ] );
return;
}
$.post( "http://localhost:8080/myApp/JobSearchItem.xhtml", request,
function( data, status, xhr ) {
cache[ term ] = data;
response( data );
});
}
});
} );
JobSearchItem Return JSON
[
{
"id": "9000",
"label": "PROGRAMMER TEST 1 (9000) ",
"value": "90000"
},
]
html
<h:body>
<f:view transient="true">
<tp:header/>
<tp:searchForm/>
<div id="results">
</div>
<h:panelGroup id="dTable" class="container">
</h:panelGroup>
</f:view>
<f:view transient="true">
<div class="jobEntity">
<div class="job-container-header">
<h4>#{testBean.jobEntity.toString()}</h4>
<c:if test="#{testBean.jobEntity.validURLConnection}">
<a href="#{testBean.jobEntity.pGradeDescriptionLink}"
class="btn btn-info-One"
target="_blank">[ Test ]</a>
</c:if>
<h4>#{testBean.jobEntity.mu} - #{testBean.jobEntity.muDescription}</h4>
<h4>#{testBean.jobEntity.specialNotes}</h4>
<h4>#{testBean.jobEntity.syRgeMnSepMsg}</h4>
</div>
<c:if test="${testBean.jobEntity.sectionToDisplay eq 'Range'}">
<table class="table">
<tbody>
<tr>
<th></th>
<c:forEach var="stepNumber" begin="1" end="#{testBean.jobEntity.stepSize}">
<th>Step #{stepNumber}</th>
</c:forEach>
</tr>
<c:forEach items="#{testBean.jobEntity.jobRows}" var="jobRow">
<tr>
<th>#{jobRow.rateType}</th>
<c:forEach items="#{jobRow.steps}" var="step">
<td>#{step.amount}</td>
</c:forEach>
</tr>
</c:forEach>
</tbody>
</table>
</c:if>
</div>
When you specify a remote URL as the datasource like this, the remote server is expected to do the filtering based on the search term given to it by the autocomplete, and return the results already filtered.
Autocomplete only carries out the filtering if you provide it with static data. See http://api.jqueryui.com/autocomplete/#option-source for more details.
N.B. If your remote server is unable to do any filtering (e.g. because it just returns a static file) then you'd have to filter the data client-side in your callback before you return it to the autocomplete. But of course this is not very efficient because you keep downloading all the data and then discarding most of it (unless the browser helpfully caches it).
Since you are calling data from a .xhtml file, it is not going to be able to filter the results, unless you can update the server side script to accept and perform activities based on data posted to it.
I would suggest you gather the static data upfront and then filter based on that. This might look something like:
$( function() {
var myData;
$.get( "http://localhost:8080/myApp/JobSearchItem.xhtml", function( data ){
myData = data;
} );
$( "#searchTextField" ).autocomplete( {
minLength: 2,
source: myData
} );
} );
This assumes that your xhtml is providing a Array of data (usually in JSON format). This can be simple:
[
"Item 1",
"Item 2",
"Item 3"
];
Or something more advanced:
[{
"label": "Item 1",
"value": 1
},{
"label": "Item 2",
"value": 2
},{
"label": "Item 3",
"value": 3
}];
If the data you get back is something else: HTML Table, XML, or text, then using a function with Source will help you. If you update your question and provide an example of the data, we could provide a more complete example or guidance.
Update 1
Given the following JSON Data:
[{
"id": "9000",
"pGrade": "0",
"label": "PROGRAMMER TEST 1"
},{
"id": "6000",
"pGrade": "0",
"label": "WEB PROGRAMMER TEST 1"
}];
This does not comply with the standard Autocomplete expected data. If you are able to POST data to JobSearchItem.xhtml, then you can have it filter first and return data. If JobSearchItem.xhtml does not accept POST, then I would perform a GET of all the data up front and then filter it later. I will include an example of both.
POST
If you are posting the data, the server-side script needs to know what data you are sending it in the form of a variable name and value. You did not supply a variable name in your example and you have not supplied the JobSearchItem.xhtml content, so it's really hard to identify how this script works.
For this example, we will use term and our example data will be we. If this was a GET command, it would look like:
JobSearchItem.xhtml?term=we
For Post we will use an Object that is submitted:
{ "term": "we" };
Here are the basics:
$(function(){
var cache = {};
$("#searchTextField").autocomplete( {
minLength: 2,
source: function(request, response){
var t = request.term;
if (t in cache){
response(cache[t]);
return;
}
var results = [];
$.ajax({
url: "http://localhost:8080/myApp/JobSearchItem.xhtml",
data: {
term: t
},
dataType: "json",
method: "POST",
success: function( data, status, xhr ) {
$.each(data, function(k, v){
results.push({
label: v.label,
value: v.label,
id: v.id,
grade: v.pGrade
});
});
cache[t] = results;
});
response(results);
});
}
});
});
So, in this case, if the user enters we, this is sent to the script, which will filter the results and will send back JSON that should look like:
[{
"id": "6000",
"pGrade": "0",
"label": "WEB PROGRAMMER TEST 1"
}];
Since Autocomplete is expecting an object containing label and value can't just be sent direct to response(). Using $.each() we can iterate the results and adjust so that it's formatted for Autocomplete.
GET
If your obSearchItem.xhtml is static and just provides a list of JSON data, using GET might be a good way to collect this data. Consider that you can get all this data up front, and then use it later. This is the most common way to use Autocomplete, but the data still has to be in the right format.
$( function() {
var myData = [];
$.get("http://localhost:8080/myApp/JobSearchItem.xhtml", function(data){
$.each(data, function(k, v){
myData.push({
label: v.label,
value: v.label,
id: v.id,
grade: v.pGrade
});
});
});
$("#searchTextField").autocomplete({
minLength: 2,
source: myData
});
});
One of these should work.

Finding difficulty trying to get the jsTree plugin to initialize in a closed state

Afternoon Everyone.
We're setting up a permissions tree for user profiles.We use the jsTree plugin found here: jQuery jsTree Plugin
Over version is: 3.1.0Their current version is: 3.1.0
Here's our usage:
/* Initialize any jsTress passed in. */
$( "." + section + "-panel-" + panel ).find( "div[class*='jstree']" ).each(function(){
$(this).jstree( { "core" : { "data" : $.parseJSON( $(this).prev().html() ) },
"plugins" : [ "checkbox","wholerow" ]
} );
/* Try to force close-all tree nodes. */
$(this).jstree( "close_all",-1 );
})
We manually try to force close all nodes here, although it doesn't work.
The JSON data passed into the initialization method includes node state attributes.
See actual data sample:
[
{
"id":"ADMIN",
"text":"ADMIN",
"state":
{
"selected":false
},
"children":
[
{
"id":"ADMIN_ADD_STAFF",
"text":"ADMIN_ADD_STAFF",
"state":
{
"opened":false,
"disabled":false,
"selected":true
}
},
{
"id":"ADMIN_NEW_MSG",
"text":"ADMIN_NEW_MSG",
"state":
{
"opened":false,
"disabled":false,
"selected":true
}
}
/* Truncated here for brevity of question. */
/* See link below for complete data object. */
]
}
]
See PasteBin for copy of complete data object.
As you can see, the opened attrib is always false, yet we find the nodes always initialize in the opened state.
Nodes will close if you manually close them.
Note: We are not using the plugin that enables node-state persistence in browser.
Just can't seem to see why the nodes won't initialize as closed...
Thanks in advance!
Make sure to call close_all after the ready.jstree event has fired:
$(this),jstree(...).on('ready.jstree', function (e, data) {
data.instance.close_all();
});
You can also simply configure jsTree not to expand the selected nodes onload:
http://www.jstree.com/api/#/?q=expand&f=$.jstree.defaults.core.expand_selected_onload
$(this).jstree({
core : {
expand_selected_onload : false,
...
Best regards,
Ivan

Select2 load JSON resultset via AJAX and search locally

Until now I've been using Select2's normal AJAX method of searching and filtering data serverside, but now I have a usecase where I want to retrieve all the results via AJAX when the select is opened and then use those results (now stored locally) to search and filter.
I've trawled the web looking for examples of how to do this and all i've found is lots of people saying the Query method should be used rather than the AJAX helper. Unfortunately I haven't found any examples.
So far all I've managed is the basic:
$('#parent').select2({
placeholder: "Select Parent",
minimumInputLength: 0,
allowClear: true,
query: function (query) {
//console.log(query);
query.callback(data);
}
});
data = {
more: false,
results: [
{ id: "CA", text: "California" },
{ id: "AL", text: "Alabama" }
]
}
Data is being passed to the select but query filtering is not implemented.
I'm struggling to understand the select2 documentation and would appreciate any assistance or links to examples.
Try the following - pre-load json data into local variable and when ready bind this to select2 object
<script>
function format(item) { return item.text; }
var jresults;
$(document).ready(function() {
$.getJSON("http://yoururl.com/api/select_something.json").done(
function( data ) {
$.jresults = data;
$("#parent").select2(
{formatResult: format,
formatSelection: format,
data: $.jresults }
);
}
)
});
</script>

How to create complex javascript object for JSON API

Below is the structure of JSON which I use to query an API
"order_items": [
{
"menu_item_id": "VD1PIEBIIG",
"menu_item_name": "Create Your Own",
"modifiers": [
{
"modifier_id": "6HEK9TXSBQ",
"modifier_name": "Shrimp"
}
],
"quantity": "1",
"total": 15.99,
"variant_id": "TXDOR7S83E",
"variant_name": "X-Lg 18\""
}
]
Now I want to call this API from an HTML page using Javascript(Using HTML elements like forms and drop down menus etc). I want to create a Javascript object with proper structure and then convert it to JSON using "stringify" function. But I am not able to create the Javascript object. Can anyone help with this?
Like i want to have the following structure
obj.order_items[0].menu_item_id="VD1PIEBIIG";
obj.order_items[0].menu_item_name="Create Your Own";
obj.order_items[0].modifiers[0].modifier_id="6HEK9TXSBQ";
and so on.
var jsonToSend = { "order_items": [ ] };
// then for each order item
var orderItem = { "menu_item_id": <whatever>,
"menu_item_name": <whatever>,
"quantity": <whatever>,
"total": <whatever>,
"variant_id": <whatever>,
"variant_name": <whatever>,
"modifiers": []
};
// then for each modifier
var modifier = { "modifier_id": <whatever>, "modifier_name": <whatever> };
orderItem.modifiers.push(modifier);
jsonToSend.order_items.push(orderItem);
JSON.stringify(jsonToSend);
Well there are a couple of ways to do this.
Manually create the Json object to send from the HTML elements:
$.ajax({
type: "POST",
url: "some.php",
data: new {"order_items": [
{
"total": $('total').Val(),
"variant_id": $('variant_id').Val(),
"variant_name": $('variant_name').Val()
}
]})
.done(function( msg ) {
alert( "Data Saved: " + msg );
});
You could use a great framework like KnockoutJs, this will keep your JSON object up to date with your form, so that you don't have to do it manually. When you are ready you just submit your original json back to the server.
See this basic example on JsFiddle
var ClickCounterViewModel = function() {
this.numberOfClicks = ko.observable(0);
this.registerClick = function() {
this.numberOfClicks(this.numberOfClicks() + 1);
};
this.resetClicks = function() {
this.numberOfClicks(0);
};
this.hasClickedTooManyTimes = ko.computed(function() {
return this.numberOfClicks() >= 3;
}, this);
};
ko.applyBindings(new ClickCounterViewModel());
You can use any number of plugins to Serialize the form, but the problem is getting the JSON structure just right.
See SerializeArray
$( "form" ).submit(function( event ) {
console.log( $( this ).serializeArray() );
event.preventDefault();
});

twitter typeahead 0.9.3 remote return URL and json object

in bootstrap 2, I used the following code to post a json object,
$('#typeahead').typeahead({
source: function (query, process) {
var URL = 'http://localhost:8080/autocomplete/search/';
var query = {"t:jsonStringField": {
"name": "model",
"value": "fusion"
},
"t:jsonStringFilter": [
{"name": "year","value": "2009"},
{"name": "make","value": "ford"}
]
};
return $.getJSON(URL,
{ query: JSON.stringify(query)},
function (data) {
return process(data);
});
}
});
Now in twitter tyeahead 0.9.3 they have done away with the source concept and moved to a remote concept, but unfortunately I do no know how to work with it.
$(".typeahead").typeahead({
remote : {
url: 'http://localhost:8080/autocomplete/search/',
replace: function(uri, query) {
var query = {"t:jsonStringField": {
"name": "model",
"value": "fusion"
},
"t:jsonStringFilter": [
{"name": "year","value": "2009"},
{"name": "make","value": "ford"}
]
};
return uri + JSON.stringify(query);
},
filter: function(response) {
return response.matches;
}
return process(resultList);
}
}
Unfortunately it doesn't work, how do I just post the JSON object rather than appending it to the string? Thanks.
In your original code you use $.getJSON. This will send a request (and expects json as result) to: http://localhost:8080/autocomplete/search/?query=%7B%22t%3AjsonStringField%22%3A%7B%22name%22%3A%22model%22%2C%22value%22%3A%22fusion%22%7D%2C%22t%3AjsonStringFilter%22%3A%5B%7B%22name%22%3A%22year%22%2C%22value%22%3A%222009%22%7D%2C%7B%22name%22%3A%22make%22%2C%22value%22%3A%22ford%22%7D%5D%7D
To do the same for Twitter's Typeahead call your replace function of your remote data should return a valid url. In your function the ?query= part of the url is missing.
You will have to set: url: 'http://localhost:8080/autocomplete/search/?query=',
You also will have to urlencode you json input maybe.
Note: you will not need the line return process(resultList); You will have to use the filter function to convert your json results to valid data:
The individual units that compose datasets are called datums. The
canonical form of a datum is an object with a value property and a
tokens property.
you could use templates to style your dropdown results, see: http://twitter.github.io/typeahead.js/examples/
By default, the dropdown menu created by typeahead.js is going to look
ugly and you'll want to style it to ensure it fits into the theme of
your web page.
You will need the additional CSS from https://github.com/jharding/typeahead.js-bootstrap.css to style the default dropdown for Bootstrap.

Categories

Resources