MeteorJS.On refreshing a page the search results get lost - javascript

I am using a searchbox for my webapp.On clicking the search button the user gets directed to the 'searchresults' page and the results are displayed.But on refreshing the page the search results are lost.How can I recover them using session?
The HTML code is:
<div class="form-group">
<input type="text" class="form-control" id='searchbox' placeholder="Search">
</div>
The js code is:
Template.navigation.events({
'submit form':function(event){
event.preventDefault();
var searchbox=document.getElementById('searchbox').value;
Router.go('/posts/search/'+searchbox);
}
});
Template.searchresults.helpers({
'post':function(){
var searchbox=document.getElementById('searchbox').value;
var search=new RegExp('\\b'+searchbox+'\\b','i');
return Posts.find({name:search});
}
});
and routerjs code is:
Router.route('/posts/search/:somesearch/',{
template:'searchresults',
name:'searchresults',
});

Instead of using a helper function, let's set the data context in your route:
Router.route('/posts/search/:somesearch/',{
template:'searchresults',
name:'searchresults',
data: function(){
return Posts.find({ name: this.params.somesearch });
}
});
Remove your post template helper entirely.
In your HTML template you'll need to iterate with {{#each this}} as this will be the cursor returned by the data function in the router.
Note, for multi-word searches and special characters you'll need to url-encode/decode the search string.

Related

Pass searchbox text as query param

I'm new to javascript.
When user enters any text or if he clicks on the search icon, i need to get the search text value and pass on that value as query param and redirect it to search results page.
Issue here is , when the page got loaded it directly redirects to the search results page without entering any text. Could you please let me know what i'm doing wrong ?
http://localhost:3000/search/searchresults.html?query=&filter=newsroom&site=allsite_all&ei=r1_search
// Only run function if the newssearch search field exists
if ($('#search_banner-q_newsroom').length >= 1) {
$("#search_banner-q_newsroom").on('keypress', setupNewsroomSearch());
}
function setupNewsroomSearch() {
var tracking;
if ($(".self-service-search").length > 0) {
tracking = "&ei=r2_pt_search";
} else {
tracking = "&ei=r1_search";
}
redirectToSearchPage($("#search_banner-q_newsroom").val(), "newsroom", "site_all", tracking);
}
<form class="search_box_wrapper">
<div class="search-box">
<input type="text" id="search_banner-q_newsroom" aria-label="Search" name="query" placeholder="Search" />
<i class="icon-magnifying-glass search_desktop-newsroom-submit"></i>
</div>
</form>
The issue is because you're calling the setupNewsroomSearch() function immediately on load and providing it's return value to the keypress handler. Instead you need to give the event handler the reference of the function, like this:
$("#search_banner-q_newsroom").on('keypress', setupNewsroomSearch); // Note: () removed
Also note that the if statement is redundant. jQuery is tolerant of calling functions on jQuery objects which matched no elements. Here's a tidied version of your JS logic:
$("#search_banner-q_newsroom").on('keypress', setupNewsroomSearch);
function setupNewsroomSearch() {
var tracking = $(".self-service-search").length > 0 ? '&ei=r2_pt_search' : '&ei=r1_search';
redirectToSearchPage($(this).val(), 'newsroom', 'site_all', tracking);
}

Passing form attributes into partials

I am working on an app with NodeJS and have been able to use handlebars and partials without much trouble. I am getting to the point where I have view and edit forms for a car.
For example, after the user submits an application I have "View" and "Edit" links that go to localhost:3000/cars/:id/view and localhost:3000/cars/:id/edit, respectively.
The only difference between these two links is that the "View" page has the form with readonly="readonly" and the "Edit" does not have the readonly attribute.
What I would like to do
cars/view
{{ >car_form readonly=true }}
cars/edit
{{ >car_form readonly=false }}
<button type="submit">Submit</button>
Is this possible with handlebars templates? Or is there something similar I can do to get the result I want?
Thank you!
You're passing in the readonly option correctly, now all you need to do is use it when rendering your form.
To do that I've used a helper to render the form via JavaScript, where we can do anything we like using the Hash Arguments funtionality Handlebars supports.
// Let's pretend this is the user input you're holding in Node.js
// and want to render in your view and edit forms.
var userInput = {
"name": "Bob",
"tagline": "Yep, I'm Bob!"
};
Handlebars.registerHelper('userForm', function(options) {
var formOpening = options.hash.readonly ? "<form readonly=\"readonly\">" : "<form>";
// Notice that I feed in `userInput` as the context here.
// You may need to do this differently, depending on your setup.
var formContents = options.fn(userInput);
return formOpening + formContents + "</form>";
});
var userFormTemplate = Handlebars.compile(document.getElementById("userForm-template").innerHTML);
var pageTemplate = Handlebars.compile(document.getElementById("page-template").innerHTML);
Handlebars.registerPartial('userForm', userFormTemplate);
document.getElementById("wrap").innerHTML = pageTemplate();
<div id="wrap"></div>
<script id="page-template" type="text/x-handlebars-template">
<h2>View</h2>
{{> userForm readonly=true}}
<h2>Edit</h2>
{{> userForm readonly=false}}
</script>
<script id="userForm-template" type="text/x-handlebars-template">
{{#userForm readonly=readonly}}
<input type="text" name="name" value="{{name}}" />
<input type="text" name="tagline" value="{{tagline}}" />
<button type="submit">Submit</button>
{{/userForm}}
</script>
<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v4.0.5.js"></script>
In the above snippet, the readonly="readonly" attribute is being added to the form beneath the "View" heading.
Note that on my browser, this does not actually make the form read-only - I'm not sure if you've got another library or something to handle that?

ng-repeat not updating information after $scope was updated

I have an ng-repeat which creates a form with some starting data. Then the user is free to modify said data and the changes should appear in the form. Before that, the user submitted data are sanitized by another function, which is called by an ng-click on a button.
Everything works well under the hood (I checked my $scope.some_array, from which ng-repeat takes the data and the new data is in the right place) but nothing happens on the page.
The element:
<li ng-repeat="field in some_array" id="field-{{$index}}">
<div class="{{field.field_color}}">
<button type="button" ng-click="save_field($index)">done</button>
{{field.nice_name}}
</div>
<div id="field-input-{{$index}}">
<input type="text" id="{{field.tag}}" value="{{field.content}}">
<label for="{{field.tag}}">{{field.nice_name}}</label>
</div>
</li>
save_field code:
$scope.save_field = function (index) {
console.log($scope.some_array[index]["content"])
var value = $("#field-" + index).children("div").children("input").val()
var name = $scope.some_array[index]["name"]
var clean_value = my_clean(value)
if (norm_value === "") {
return
}
$scope.some_array[index]["content"] = clean_value
console.log($scope.some_array[index]["content"])
}
On the console I see:
10.03.16
10/03/16
Which is right, but in the form I only see 10.03.16. I already tried putting $timeout(function(){$scope.$apply()}) as the last line of my function, but the output is still the same.
You shouldn't use input like this if you want to bind a variable to it. Digest loop will refresh the value but it will not be updated visibly because this is not html native behavior.
Use ng-model instead, it will update view value of the input as expected:
<input type="text" id="{{field.tag}}" ng-model="field.content">
Also using ng-model your variable will be updated when user modify the input, so you can retrieve it to do some treatments much more easily in save_field function, without jQuery:
$scope.save_field = function (index) {
if (norm_value === "") {
return;
}
$scope.some_array[index]["content"] = my_clean($scope.some_array[index]["content"]);
};
More infos: https://docs.angularjs.org/api/ng/directive/ngModel

How to render HTML with jQuery from an AJAX call

I have a select box with a list of books. The user can select a book and hit the submit button to view the chapters on a separate page.
However, when the user changes the select box, I would like a partial page refresh to display the past notes the user entered on the book, and allow the user to write a new note for that book. I do not want the review and creation of notes for a particular book done on the next page with the chapters, as it will clutter it up.
I'm using Python/Bottle on the backend and its SimpleTemplate engine for the front end.
Currently, when the select box is changed, an ajax call receives a Json string containing the book information and all the notes. This json string is then converted into a json object via jQuery.parseJson().
What I would like to be able to do is then loop over the notes and render a table with several cells and rows.
Would I have to do this in jQuery/js (instead of bottle/template framework) ? I assume so as I only want a partial refresh, not a full one.
I'm looking for a piece of code which can render a table with variable numbers of rows via jQuery/js from a json object that was retrieved with ajax.
<head>
<title>Book Notes Application - Subjects</title>
<script src="http://code.jquery.com/jquery-latest.min.js"
type="text/javascript"></script>
<script>
$(document).ready(function(){
$('#subject_id').change(function(){
var subject_id = $(this).val();
$.ajax({
url : "subject_ajax?subject_id=" + subject_id,
success : function(data) {
alert(data)
json = jQuery.parseJSON(data);
},
error : function() {
alert("Error");
}
});
})
})
</script>
</head>
<body>
<!-- CHOOSE SUBJECT -->
<FORM action="/books" id="choose_subject" name="choose_subject" method="POST">
Choose a Subject:
<select name="subject_id" id="subject_id">
% for subject in subjects:
<option value="{{subject.id}}">{{subject.name}}</option>
% end
</select><input type="submit" name="sub" value="Choose Subject"/>
<BR />
</FORM>
This greatly depends on how your JSON and HTML are formatted. But with a table somewhere like:
<table id="books">
<tr>
<th>Chapter</th>
<th>Summary</th>
</tr>
</table>
You could do something like:
$(function(){
$('#choose_subject').submit(function () {
var subject_id = $(this).val();
$.getJSON("subject_ajax?subject_id=" + subject_id, function(data) {
console.log(data);
$.each(data.chapters, function (index, chapter) {
$('#books').append('<tr><td>' + chapter.title + '</td><td>' + chapter.summary + '</td></tr>');
})
});
return false;
})
})
This supposes JSON like:
{
"notes": [
"Note 1",
"Note 2"
],
"chapters": [
{
"title": "First chapter",
"summary": "Some content"
},
{
"title": "Second chapter",
"summary": "More content"
}
]
}
Other notes:
If you use HTML 4 or earlier, keep all your tags in upper case. If you're using XHTML or HTML5, keep all your tags in lower case.
You don't need $(document).ready(function () {...}), with recent versions of jQuery $(function () {...} ) works the same and it's easier to read.
You can use $.get instead of $.json if you're only using the success state (as you are here). And if you're confident that the data you'll get is valid JSON, you can use getJSON instead of get. It will parse the JSON for you deliver it to you as a JavaScript object automatically.
It's usually more convenient to use console.log rather than alert when you're testing. Actually, it's usually a bad idea in general to ever use alert.
I'm not familiar with Python/Bottle or its SimpleTemplate engine, but you could consider generating the html for the table on the server side and returning it in the ajax response, rather than returning JSON.
var subject_id = $(this).val();
$.ajax('subject_ajax', {
type: 'get',
data: { subject_id: subject_id },
dataType: 'html',
success : function(html) {
// Insert the html into the page here using ".html(html)"
// or a similar method.
},
error: function() {
alert("Error");
}
});
When calling .ajax():
The "type" setting defaults to "get", but I prefer to explicitly set it.
Use the "data" setting for the ajax call to specify the URL parameter.
Always specify the "dataType" setting.
I also recommend you perform the ajax call in an on-submit handler for the form, and add an on-change handler for the select that submits the form.
$(document).ready(function(){
$('#subject_id').change(function() {
$(this.form).submit();
});
$('#choose_subject').submit(function(event) {
event.preventDefault();
var subject_id = $('#subject_id').val();
if (subject_id) {
$.ajax(...);
}
});
});
This way your submit button should work in case it is clicked.
There are a few things you need to look at:
1) Is your SimpleTemplate library included?
2) Have you compiled your template via compileTemplate()?
Once you know your library is included (check console for errors), pass your data returned to your success handler method, compile your template, that update whichever element you are trying to update.
I'm not sure that you want to update the same element that you're defining your template in.
$(document).ready(function(){
$('#subject_id').change(function(){
var subject_id = $(this).val();
$.ajax({
url : "subject_ajax?subject_id=" + subject_id,
success : function(data) {
var template_data = JSON.parse(data);
var template = $('#subject_id').toString(); // reference to your template
var precompiledTemplate = compileTemplate(template);
var result = precompiledTemplate(template_data);
$('#subject_id').append(result);
},
error : function() {
alert("Error");
}
});
})
})
You might also try moving your template out of the element you're trying to update like this:
<script type="text/template" id="subject-select-template">
% for subject in subjects:
<option value="{{subject.id}}">{{subject.name}}</option>
% end
</script>
Then just create a blank select element like so:
<select id="select_id"></select>
Update references. Anyway, hope this is helpful. It should work but I can't test without your specific code ;)
Also, check out this demo example if you haven't yet:
https://rawgithub.com/snoguchi/simple-template.js/master/test/test.html

How to call ajax and output its result inside div and textarea?

I am trying to make load more button. My goal is to call ajax and put the response inside div and textarea.how to place the response inside div and textarea? Currently the response only shows in messagebox but i want to append the result into div.
*Note:*Response is html hyperlinks produced by process.php and i want those hyperlinks placed inside the div
<html>
<head>
<script>
//initialize page number to 1 default
var pagenumber=1;
//pass pagenumber to function to fetch correct page records
function getResult(pagenumber){
alert('me here'+pagenumber);
$.ajax(
{
type: 'GET',
url: './process.php?ID=1234&type=1&moviePath=1234/1212/Love&title=Love&page='+pagenumber,
data: $("#myform").serialize(),
data: {
},
success: function (good)
{
//handle success
alert(good)
},
failure: function (bad)
{
//handle any errors
alert(bad)
}
});
//after every call increment page number value
pagenumber++;
}// end of getResult Function
function addMoreItems()
{
pagenumber++;
getResult(pagenumber);
}
</script>
</head>
<body>
<div id="myDiv"></div>
<div class="MoreButtonSection">
<div class="RedButton">
<span class="LeftEnd"></span>
<span class="Centre">see more</span>
<span class="RightEnd"></span>
</div>
</div>
<br>
<br>
<form id="myform" name="myform" action="./2.php?Id=&title=" method="post">
<td>
<textarea rows="7" cols="15" name="outputtext" style="width: 99%;"></textarea>
</td>
</form>
</html>
You say your result is only showing in the message box, instead of alerting it, simply append. Assuming the below div is what you want to append to:
<div id="myDiv"></div>
You can modify your success function:
success: function (good)
{
//handle success
$("#myDiv").append(good);
},
Also, get rid of that second data: {}, -- it's doing nothing.
There are a number of issues.
There is no indication that you've included jQuery.
You've declared data: twice.
As Dmitry pointed out, you should probably be posting this.
And finally, where are you actually calling getResult()? It doesn't look like it's being called.
In addition, it is worth noting that from jQuery 1.8 and higher, .success() and .failure() are now deprecated and have been replaced with .done() and .fail().
http://api.jquery.com/jQuery.ajax/
I tend to use jQuery in these situations to make life a little easier, and work with the $('#yourDiv').append() function. For instance you can create variables i.e. var mug; and once it is filled with your data append mug to the document through $('#yourDiv').append("<p>"+mug+"</p>);
An example - Ajax Twitter API call that returns tweets to specific lists within a div (page source)
Hope that helps!
I think I get what you are trying to do but that code is a mess. As #David L has stated, you need jQuery. But then you do not need all the code you have written. It can be done in a few simple lines. Please replace the actual element selectors with your correct ones.
function addMoreItems() {
pagenumber++;
// get form values
var params = $('#myform').serializeArray();
// add predefined values
params.push({name: 'ID', value: '1234'});
params.push({name: 'type', value: '1'});
params.push({name: 'moviePath', value: '1234/1212/Love'});
params.push({name: 'title', value: 'Love'});
params.push({name: 'page', value: pagenumber});
// do request and insert response from server in div with id='divresults'
$.get('process.php', params, function(data) {
$('#divResults').append(data);
});
}

Categories

Resources