jquery mobile multipage with javascript template, does not always "refresh" - javascript

I have a multi-page jQuery mobile page.
When I go from Page 1 to Page 2 I see my template that I dynamically create using handlebars.
The template:
<script id="history-template" type="text/x-handlebars-template">
<div data-role="collapsible" id="share_history" >
<h3>{{share_title}}</h3>
{{#each historyItem}}
<h2>Shared with {{shared_with}}</h2>
{{#list people}}{{firstName}} {{lastName}}, {{role}}{{/list}}
{{/each}}
</div>
</script>
The javascript:
var context = {
share_title: "View Share History",
historyItem: [
{
shared_with: "with a group",
people: [
{firstName: "Bob", lastName: "Wong", role: "Dad" },
{firstName: "Tina", lastName: "Turner", role: "Guardian" },
{firstName: "Modest", lastName: "Mouse", role: "Dad" }
]
},
{
shared_with: "with 3 people",
people: [
{firstName: "Baily", lastName: "Wong", role: "Dad" },
{firstName: "Gina", lastName: "Turner", role: "Guardian" },
{firstName: "Modest", lastName: "Mouse", role: "Dad" }
]
}
]
};
var source = $("#history-template").html();
var template = Handlebars.compile(source);
Handlebars.registerHelper('list', function(people, options) {
var out = "<ul class=>";
for(var i=0, l=people.length; i<l; i++) {
out = out + "<li>" + options.fn(people[i]) + "</li>";
}
return out + "</ul>";
});
var html = template(context);
$('#share').html(html);
$.mobile.changePage('#add-edit');
When I go from Page 1 to Page 2 (in my multipage layout) it works (good).
But if I click the back button, and then go back to Page 2, I see my content...minus the additional markup jQuery mobile adds (i.e. I see content but not my jQuery mobile appearance/theme).
Edit
For my example, I had to do the following:
$('#share').html(html).trigger( "create" );

You will need to trigger the create event on the html element, e.g
el.trigger('create');

Related

Accessing nested json in ExpandRow of bootstrap table react component

I have a bootsrap table react component and I will like to add the nested json record as a table when each row in the bootstrap table, the row should expand and show the nested json has a table. However, I can not access the nested json in the expand row function.
My Goal: Presently I have a table showing the data of the outer json in a table. However, I want the elements in the the nested json summary to be represented in a table when each row is clicked.
const userList = [
{ id: 1, firstName: "james", lastName: "smith", age: 20,summary:{city:'lag', min:12} },
{ id: 2, firstName: "alex", lastName: "green", age: 20 , summary:{city:'lao', min:121}},
{ id: 3, firstName: "may", lastName: "jones", age: 18, summary:{city:'dag', min:112} }
];
columns=[
{text:'id',dataField:id},
{text:'firstName',dataField:id firstName},
{text:'lastName',dataField: lastName}
]
const expandRow = {
renderer: row => (
<BoostrapTable data={userList} columns={row.columns.summary}/>
)
};
<BoostrapTable data={userList} columns={columns} keyField="id expandRow={ExpandRow}/>
You are using the wrong variable, it's not rows, but row:
const expandRow = {
renderer: row => (
<BoostrapTable data={[row.summary]} columns={{text:'city',dataField:'city'},
{text:'min',dataField:'min'}}/>
)
};

How to fix [object Object] and render from a has many relationship in Javascript?

I'm working a show page with Ajax where I have an educational course rendered with the course instructor but Im getting [object Object] when trying to set the students of that particular course. I would like to render all the students for the course.
I tried adding students as an attribute to the course serializer.
class CourseSerializer < ActiveModel::Serializer
attributes :id, :name, :instructor, :students
has_many :ratings
has_many :students, through: :ratings
end
This is my click event.
$(document).on('click','.show_link',function(e) {
e.preventDefault()
$('.ajaxStyling').html('')
let id = $(this).attr('data-id')
fetch(`/courses/${id}.json`)
.then(res => res.json())
.then(course => {
let newCourse = new Course(course)
let courseHtml = newCourse.formatShow()
$('.ajaxStyling').append(courseHtml)
})
})
Constructor function.
function Course(course) {
this.id = course.id
this.name = course.name
this.instructor = course.instructor
this.students = course.students
}
Prototype function.
Course.prototype.formatShow = function () {
let courseHtml = `
<h3 class="showText">${this.name} by ${this.instructor}</h3>
${this.students}.forEach(function(student) {
return "<p>" + student.first_name + "</p>"
})
`
return courseHtml
}
But Im getting the following error in page.
This renders as a link which works as intended --> Adobe Analytics 201 by Adam Greco
But the following is not right. Code rendered in page below the link above-->
[object Object],[object Object],[object Object].forEach(function(student) {
return "" + student.first_name + "" })
This is the data in my network request.
{id: 6, name: "Adobe Analytics 201", instructor: "Adam Greco",…}
id: 6
instructor: "Adam Greco"
name: "Adobe Analytics 201"
ratings: [{id: 29, rating: 2, course_id: 6, student_id: 11, created_at: "2019-05-23T00:54:22.813Z",…},…]
students: [{id: 11, first_name: "Stefan", last_name: "Candelaria"}]
0: {id: 11, first_name: "Stefan", last_name: "Candelaria"}
1: {id: 12, first_name: "Robby", last_name: "Pasurin"}
2: {id: 10, first_name: "Rafa", last_name: "Lopez"}
Don't try doing everything inside the template literal string. Also forEach doesn't do anything with return
Try something like:
Course.prototype.formatShow = function() {
let courseHtml = `
<h3 class="showText">${this.name} by ${this.instructor}</h3> `;
courseHtml += this.students.map(function(student) {
return `<p>${student.first_name}</p>`;
}).join('');
return courseHtml
}

print javascript array in html

Not sure how to print results onto HTML. I can do so through alerts. How do I print on the browser?
<!DOCTYPE html>
<html>
<body>
<script>
var parsed = "";
var myObject = [{
firstname: "Jane",
lastname: "Doe",
email: "jdoe#email.com"
}, {
firstname: "Ja",
lastname: "joe",
email: "je#email.com"
}, {
firstname: "Janet",
lastname: "joes",
email: "jsse#email.com"
}];
for (i = 0; i < myObject.length; i++) {
var myobj = myObject[i];
for (var property in myobj) {
parsed += property + ": " + myobj[property] + "\n";
alert(property);
alert(myobj[property]);
}
}
alert(parsed);
</script>
</body>
</html>
Not sure how to print results onto HTML. I can do so through alerts.
How can I print on the browser?
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<textarea id="display" style="width:1000px;height:1000px"></textarea>
<script>
var parsed = "";
var myObject = [{
firstname: "Jane",
lastname: "Doe",
email: "jdoe#email.com"
}, {
firstname: "Ja",
lastname: "joe",
email: "je#email.com"
}, {
firstname: "Janet",
lastname: "joes",
email: "jsse#email.com"
}];
for (i = 0; i< myObject.length; i++) {
var myobj= myObject[i];
for (var property in myobj) {
parsed += property + ": " + myobj[property] + "\n";
}
}
$("#display").val(parsed);
</script>
</body>
</html>
Create an element e.g. div or label inside the html body with a specific attribute e.g.class,id,name
HTML
<label id="arrayMessage"> </label>
Javascript
document.getElementById('arrayMessage').innerHTML = parsed ;
Jquery
$("#arrayMessage").html(parsed);
You can use other attributes of elements to fetch them by class,name or html tag type.
You could use the simple:
document.write([1,2,3]);
But that ain't going to be too pretty and will override the existing page content.
You could do this:
...
<body>
<div id="data"></div>
</body>
<script>
var data = document.getElementById('data');
myObject.forEach(function(element) {
var firstname = document.create('div');
var lastname = document.create('div');
var email = document.create('div');
firstname.innerHTML = element.firstname;
lastname.innerHTML = element.lastname;
email.innerHTML = element.email;
data.appendChild(firstname);
data.appendChild(lastname);
data.appendChild(email);
});
</script>
...
Create an element in your HTML page that will contain the output and assign it an appropriate unique id, such as "target-id".
<html>
<body>
...
<div id="target-id"></div>
...
</body>
</html>
Then use the method below to insert the desried text/HTML into that element.
document.getElementById('target-id').innerHTML = 'html data';
See also: Inserting HTML into a div
For the easiest solution is to use the JSON.stringify() with the indent option and using the tag. JSON.stringify(JSON,null,4) 4 space indent.
let pre = document.getElementById('output');
let jstring = JSON.stringify({ a: 1, b:2,c:3 }, null, 4);
pre.textContent = jstring;
pre{
border:1px solid grey;
min-height:10em;
<pre id="output"></pre>
This is a simple solution we convert the array of objects to a string using JSON.stringify(). hope that it what you want to do.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<p id="elements"> </p>
<script>
var myObject = [{
firstname: "Jane",
lastname: "Doe",
email: "jdoe#email.com"`enter code here`
}, {
firstname: "Ja",
lastname: "joe",
email: "je#email.com"
}, {
firstname: "Janet",
lastname: "joes",
email: "jsse#email.com"
}];
myObject.forEach(element => {
document.getElementById("elements").innerHTML= JSON.stringify(myObject);
});
</script>
</body>
</html>

Search by name and family but display account number in jquery autocomplete

I'm working on a piece of code which has used jquery ui autocomplete component in order filter searched items. I have to configure it in order to be available to search based on multi ple factors, here is my sample search array:
var availableTags = [{
name: "Smith",
family: "Johnson",
account_number: "10032",
nick_name: "Friend account",
}, {
name: "Susan",
family: "Rice",
account_number: "343243",
nick_name: "Mom Account",
}, {
name: "Joe",
family: "Austin",
account_number: "3434",
nick_name: "Partner Account",
}, {
}];
the auto complete should display name, family, account number and nick_name when displaying the suggestion box. but when each item is selected only the account_number must be inserted into the text box. user must also be able to search through name, family, account number and nick name all of them. How can i achieve this target?
You need to:
Revise the data array to contain the value parameter (this allows autocomplete to fill the input upon focus/select)
Write a custom source function that filters the data based on what user has typed
Write a custom _renderItem function that displays the data formatted to your liking
So you have:
var userData = [{
name: "Smith",
family: "Johnson",
value: "10032",
nick_name: "Friend account"
}, {
name: "Susan",
family: "Rice",
value: "343243",
nick_name: "Mom Account"
}, {
name: "Joe",
family: "Austin",
value: "3434",
nick_name: "Partner Account"
}];
$("#autocomplete").autocomplete({
source: function (request, response) {
var search = $.trim(request.term.toLowerCase());
var array = $.grep(userData, function (val) {
return
val.name.toLowerCase().indexOf(search) >= 0 ||
val.family.toLowerCase().indexOf(search) >= 0 ||
val.value.toLowerCase().indexOf(search) >= 0 ||
val.nick_name.toLowerCase().indexOf(search) >= 0;
});
response(array);
}
})
.data("ui-autocomplete")._renderItem = function (ul, item) {
var $a = $("<a></a>").text(item.name + " " + item.family);
$("<br />").appendTo($a);
$("<small></small>").text(item.nick_name).appendTo($a);
$("<br />").appendTo($a);
$("<small></small>").text(item.value).appendTo($a);
return $("<li></li>").append($a).appendTo(ul);
};
Demo here

Failing to create an ajax request to handelbars.js template

I am trying to create an AJAX request (using jQuery) for handelbars.js (an by that grasp the concept of using template.
I have this data object and ajax request:
var data = { users: [
{username: { firstName: "Alan", lastName: "Johnson" } , email: "alan#test.com" },
{username: { firstName: "Allison", lastName: "House" } , email: "allison#test.com" },
{username: { firstName: "Ryan", lastName: "Carson" }, email: "ryan#test.com" }
]};
$(document).ready(function(){
$.get('h1template.js', function(template_text){
var template = Handlebars.compile(template_text);
var html = template(data);
$('#content').html(html);
});
});
this is the content of h1template.js:
<table>
<thead>
<th>Username</th>
<th>Real Name</th>
<th>Email</th>
</thead>
<tbody>
{{#users}}
<tr>
<td>{{username}}</td>
<td>{{firstName}} {{lastName}}</td>
<td>{{email}}</td>
</tr>
{{/users}}
</tbody>
</table>
Something obviously is not right because this is not working
What is wrong?
Is it something silly I do wrong with the ajax call itself? Calling it ".js" and not ".php" (for example)?
(I run the file inside my localhost and when looking on the network properties the 'h1template.js' status is 304-not-modified)
Because the template name is .js, it is being parsed as a javascript file. So you need to change it to either .html or .php or whatever you like.
Also in the users object, the username is an object, so in the template outputting {{username}} will only give you [object, object]. You need to change it to something like {{username.name}}
I played a bit with the code and found out how to write it
the h1template.html file (instead of *.js"):
<table>
...
</table>
and the script in main page is:
var data = { users: [
{username: { firstName: "Alan", lastName: "Johnson" } , email: "alan#test.com" },
{username: { firstName: "Allison", lastName: "House" } , email: "allison#test.com" },
{username: { firstName: "Ryan", lastName: "Carson" }, email: "ryan#test.com" }
]};
$(document).ready(function(){
$.get('h1template.html', function(template_text){
var source = template_text;
var template = Handlebars.compile(source);
var html = template(data);
$('#content').html(html);
});
});

Categories