Related
my problem after write as object literal as Jquery guide i can't using $(this) to access self on onlick="". please help correct my mistake.
my html
<a
data-id="<?=$product_id?>"
class="compare product-<?=$product_id?>"
onclick="(function(){compareInit.comGet();})()"
></a>
my js
var compareInit = {
/* Store Item Compare */
comGet: function() {
var e = $(this);
var item_id = e.data('id');
var item_image = e.find(".compare-hidden-image").val();
var item_name = e.find(".compare-hidden-name").val();
var count_item = $(".compare-item").length;
var item_dialog = $(".compare-tray-dialog");
var compare_button = $(".compare-tray-item");
item_dialog.show();
if (count_item > 1) {
} else {
$(".product-"+ item_id).css("color", "red").attr('onclick','');
}
if (count_item === 0) {
compare_button.removeClass('activate').addClass('deactivate');
} else {
compare_button.removeClass('deactivate').addClass('activate');
}
$('.compare-remove').on("click", function() {
var rem_id = $(this).data('id');
$("." + rem_id).remove();
$(".product-" + rem_id).css("color", "#fff").attr('onclick','(function(){compareInit.comGet();})()');
compare_button.removeClass('activate').addClass('deactivate');
});
}
};
Thank in advance.
You can pass the this identifier from the onclick event and then access it under a name other than this such as elem as a parameter of your function.
var compareInit = {
/* Store Item Compare */
comGet: function(elem) {
console.log("working");
var e = $(elem);
var item_id = e.data('id');
var item_image = e.find(".compare-hidden-image").val();
var item_name = e.find(".compare-hidden-name").val();
var count_item = $(".compare-item").length;
var item_dialog = $(".compare-tray-dialog");
var compare_button = $(".compare-tray-item");
item_dialog.show();
if (count_item > 1) {} else {
$(".product-" + item_id).css("color", "red").attr('onclick', '');
}
if (count_item === 0) {
compare_button.removeClass('activate').addClass('deactivate');
} else {
compare_button.removeClass('deactivate').addClass('activate');
}
$('.compare-remove').on("click", function() {
var rem_id = $(this).data('id');
$("." + rem_id).remove();
$(".product-" + rem_id).css("color", "#fff").attr('onclick', '(function(){compareInit.comGet();})()');
compare_button.removeClass('activate').addClass('deactivate');
});
}
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a data-id="3636" class="compare product-3636" onclick="compareInit.comGet(this)">Testing</a>
You need to pass-on the your required DOM element's this reference as follows:
onclick="(function(){compareInit.comGet();})()"; here you are invoking an anonymous function without passing anything to it. So there inside it this reference means that anonymous function itself. To achieve your goal you need to pass DOM reference as follows:
var compareInit = {
/* Store Item Compare */
comGet: function(thisRef) {
alert($(thisRef).text());
}
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="mydiv" onclick="(function(thisRef){compareInit.comGet(thisRef);})(this)">Click Me!</div>
Try this: apply the this inside the onclick function .If you apply this in object function its get the data from that object only
var compareInit ={
comGet : function(that){
console.log(that.innerHTML)
}
}
<a onclick="compareInit.comGet(this)">hello</a>
Alternate:
If get the this from whole object try with return like below .its like a jquery object $(element).html()
var compareInit = function(that){
return {
comGet : function(){
console.log(that.innerHTML)
}
}
}
<a onclick="compareInit(this).comGet()">hello</a>
I am trying to use jQuery to add buttons on a page. I would like the buttons to appear vertical instead of horizontal. So I try
$(".guess").append("<p>" + guess_answer + "</p>");
But then it prints to the page:
[object Object]
[object Object]
[object Object]
[object Object]
Instead of the buttons. I have test the code without the paragraph tags and it works but doesn't when the html is place in it.
var question1 = {
question: "What is 4 times 1?",
answer: "Dream On",
possible: [1,2,3,4],
boolean: [true,false,false,false]
};
function generate () {
$(".question").html(question1.question);
for (var i = 0; i < question1.possible.length; i++) {
var guess_answer = $('<button>');
guess_answer.addClass("options text-center btn-group-lg");
guess_answer.attr({
"data-boolean" : question1.boolean[i]
});
guess_answer.text(question1.possible[i]);
//guess_answer.append(question1.possible[i]);
$(".guess").append("<p>" + guess_answer + "</p>");
}
}
Use guess_answer.prop("outerHTML") to get the element as HTML string
var question1 = {
question: "What is 4 times 1?",
answer: "Dream On",
possible: [1,2,3,4],
boolean: [true,false,false,false]
};
function generate () {
$(".question").html(question1.question);
for (var i = 0; i < question1.possible.length; i++) {
var guess_answer = $('<button>');
guess_answer.addClass("options text-center btn-group-lg");
guess_answer.attr({
"data-boolean" : question1.boolean[i]
});
guess_answer.text(question1.possible[i]);
//guess_answer.append(question1.possible[i]);
$(".guess").append("<p>" + guess_answer.prop("outerHTML") + "</p>");
}
}
Its because guess_answer as defined in your generate function contains a button object, you cannot append a HTML entity combining it with html tags using append.
If you want to add a button to the HTML, then simply write it in the append like so:
$(".guess").append("<p><button value='123'/></p>");
However you should use the class name to append HTML content, whilst it is valid, a class might not be unique and if you add content with ID's then you may create multiple instances with the same ID which isn't valid.
Your variable guess_answer is an object, more specifically a jQuery object holding a DOM node.
Use DOM methods to insert it
function generate() {
$(".question").html(question1.question);
for (var i = 0; i < question1.possible.length; i++) {
var guess_answer = $('<button />', {
'class' : 'options text-center btn-group-lg',
'data-boolean' : question1.boolean[i],
text : question1.possible[i]
}),
p = $('<p />');
$(".guess").append( p.append(guess_answer) );
}
}
I tried using appendTo(...) - like this
guess_answer.appendTo('.guess');
See code below:
var question1 = {
question: "What is 4 times 1?",
answer: "Dream On",
possible: [1, 2, 3, 4],
boolean: [true, false, false, false]
};
function generate() {
$(".question").text(question1.question);
for (var i = 0; i < question1.possible.length; i++) {
var guess_answer = $('<button>');
guess_answer.addClass("options text-center btn-group-lg");
guess_answer.attr({
"data-boolean": question1.boolean[i]
});
guess_answer.text(question1.possible[i]);
//guess_answer.append(question1.possible[i]);
var newPar = $("<p>");
newPar.appendTo('.guess');
guess_answer.appendTo(newPar);
}
}
generate();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="question"></div>
<div class="guess"></div>
I got one external .json file, in which a arry is defined as:
var words = [
"a",
"able",
"about",
"account",
"acid",
"across",
"act",
"addition"]
My plan is to import in the .json file via jquery, and then use the values in the array word as the option in a select object.
My understanding is:
<div>
<select size="7" class="selection"></select>
</div>
<script>
$(document).ready(function () {
$.getJSON("words-small.json", function (result) {
$.each(result, function (i, word) {
$(".selection").html("<option>word</option>");
});
});
});
</script>
or:
<script>
$(document).ready(function () {
$.getJSON("words-small.json", function (result) {
html = ''
for (i = 0; i < results.length; i++) {
html += "<option value=" + result[i] + ">" + result[i] + "</option>";
};
document.getElementById("myselect").innerHTML = html;
});
});
</script>
But neither works here. Please tell me how to fix that.
Your .json-file needs to be like this:
[
"a",
"able",
"about",
"account",
"acid",
"across",
"act",
"addition"
]
Then either of the scripts should work. (First one with one small adjustment)
<div>
<select size="7" class="selection"></select>
</div>
<script>
$(document).ready(function () {
$.getJSON("words-small.json", function (result) {
$.each(result, function (i, word) {
$(".selection").append("<option>"+word+"</option>");
});
});
});
</script>
Remember that a .json-file should only contain JSON. Not javascript which is what you had.
You have some typos in your code.
Assuming that you have valid json and parsed words array
var words = [
"a",
"able",
"about",
"account",
"acid",
"across",
"act",
"addition"];
$.each(words, function (i, word) {
$(".selection").append("<option value='"+word+"'>" + word + "</option>");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<select size="7" class="selection"></select>
</div>
For your first attempt, you're doing:
$(".selection").html("<option>word</option>");
You should be using something like append, and also make sure you take "word" out of the quotes:
$(".selection").append("<option>" + word + "</option">);
.html() just replaces the data contained within the HTML element, whereas .append() will add them to the end.
This is the issue if you're only getting one value returned.
It looks like in your JSON object you have the data defined in a variable, instead it should just be:
[
"a",
"able",
"about",
"account",
"acid",
"across",
"act",
"addition"
]
this work for me:
$.each(words, function (i, word) {
items+="<option>"+word+"</option>";
});
$(".selection").html(items);
You have several things that need to be fixed. One, is that .html() replaces the innerHTML, doesn't add to it. So, you need to build all the options and then set them. I also, as you had in the second script, put the value of the word as the option value. Note, the inner quotes are also needed. Furthermore, your jQuery of ".selection" will do this to all objects designated with the "selection" class, whereas, in your second script, you seemed to want to only assign one element with an id of "myselect".
<div>
<select size="7" class="selection"></select>
</div>
<script>
$(document).ready(function () {
$.getJSON("words-small.json", function (result) {
var html = "";
$.each(result, function (i, word) {
html += "<option value='"+word+"'>"+word+"</option");
});
$(".selection").html(html);
});
});
</script>
You can extend jQuery. The best thing about this approach is you can reuse these extensions when needing to clear or fill a select. Just pass it an array.
$.fn.clearSelect = function() {
return this.each(function() {
if (this.tagName == 'SELECT')
this.options.length = 0;
});
}
$.fn.fillSelect = function(data) {
return this.clearSelect().each(function() {
if (this.tagName == 'SELECT') {
var dropdownList = this;
if (data.length > 0) {
this.disabled = false;
}
$.each(data, function(index, optionData) {
var option = new Option(optionData, optionData);
dropdownList.add(option, null);
});
}
});
}
This extension will allow you to pass your data directly to the select like this
$("#myselectid").fillselect(["a","able","about","account","acid","across","act"]);
I have not tested this, but the snip-it should give you the general idea.
But in your example you could call the extensions this way:
$(document).ready(function () {
$.getJSON("words-small.json", function (result) {
$(".selection").fillSelect(result);
}
});
Just tested and edited the snipet. Test is located here https://jsfiddle.net/4wmj8pkk/
<!-- The select drop down menu (works fine) -->
<select id="select-event-type">
<?php foreach ($this->events as $event) {
echo "<option value='" .$event->event_id. "'>" .$event->event_title."</option>";
}?>
</select>
<!-- The javascript, which is supposed to output something according to the chosen option in the select drop down -->
<script>
(function ($) {
var events = <?php echo (count($this->events) > 0) ? json_encode($this->events) : "null"; ?>;
$(document).ready(function() {
$('#select-event-type').change(function() {
if (events) {
var event = events[this.selectedIndex];
$('#event-details').html(event);
}
});
});
})($);
</script>
<!-- In this div the output will be displayed -->
<div id="event-details"></div>
The event variable undefined.
If I for example do this: var event = 'hello' It does output 'hello' as it is supposed to.
So the problem seems to be with this part: events[this.selectedIndex];. What did I do wrong?
I am really new to this. Thank you so much for your help!!
UPDATE:
Console output (in chrome):
<script>
(function ($) {
var events = JSON.parse({"1":{"event_id":"1","event_title":"event1","event_desc":"event1","event_location":"eventlocation","event_requirements":"event1","event_date":"2022-07-20 15:00:00"},"2":{"event_id":"2","event_title":"event2","event_desc":"event2","event_location":"eventlocation","event_requirements":"event2","event_date":"2015-04-20 15:00:00"},"3":{"event_id":"3","event_title":"event3","event_desc":"event3","event_location":"eventlocation","event_requirements":"event3","event_date":"2019-11-20 16:00:00"}}); $(document).ready(function() {
$('#select-event-type').change(function() {
if (events) {
var event = events[$(this).selectedIndex];
$('#event-details').html(event);
}
});
});
</script>
JSON:
{
"1": {
"event_id": "1",
"event_title": "event1",
"event_desc": "event1",
"event_location": "eventlocation",
"event_requirements": "event1",
"event_date": "2022-07-20 15:00:00"
},
"2": {
"event_id": "2",
"event_title": "event2",
"event_desc": "event2",
"event_location": "eventlocation",
"event_requirements": "event2",
"event_date": "2015-04-20 15:00:00"
},
"3": {
"event_id": "3",
"event_title": "event3",
"event_desc": "event3",
"event_location": "eventlocation",
"event_requirements": "event3",
"event_date": "2019-11-20 16:00:00"
}
}
To get the value of the select element use this.value. Thus change:
var event = events[this.selectedIndex];
To:
var event = events[this.value];
However, if you json is an array with indices 0,1,2,3,4 rather than an object with option values as keys then your use of this.selectedIndex is correct.
UPDATE:
In the light of the sample JSON posted the correct code should be:
var event = events[this.selectedIndex + 1].event_title;
Special Note
You can get all the event data by using either:
var event = JSON.stringify( events[this.selectedIndex + 1] ); //gives you a string of everything
Or you could construct how you want it to look like so:
var event = $('<div/>');
$.each( events[this.selectedIndex + 1], function(k,v) {
event.append( $('<div/>',{text:k + ': ' + v}) );
});
See this answer for the jQuery way of accessing the selectedIndex property. Your answer might look like:
var event = events[$(this).prop("selectedIndex")];
Firstly you dont need the 2 ready instances. Try to do it, if dont work please tell me.
<script>
$(document).ready(function() {
var events = <?php echo (count($this->events) > 0) ? json_encode($this->events) : "null"; ?>;
$('#select-event-type').change(function() {
if (events) {
var event = events[$(this).selectedIndex];
$('#event-details').html(event);
}
});
});
</script>
and what means the selectedIndex ?
I'm trying to display particular json data in a form of Bullets. Each chapter data into <li>, each title into <p> and make those titles as a link. Finally, consider to the index of clicked title display related content in a second <div>. I have already some piece of code below (not working yet).
Html:
<div id="page1">
<ul id="courses"></ul>
</div>
<div id="page2">
<p id="content"></p>
</div>
JS code:
var jsonString = '[{"chapter":"General","title":"News forum","content":"Text1"},
{"chapter":"CHAPTER 1","title":"1.1 Introduction","content":"Text2"},
{"chapter":"CHAPTER 1","title":"1.2 Main Idea","content":"Text3"},
{"chapter":"CHAPTER 2","title":"2.1 Architecture","content":"Text4"},
{"chapter":"CHAPTER 3","title":"3.1 Liter.overview","content":"Text5"}]';
var myData = JSON.parse(jsonString);
$(document).ready(function() {
var $clist = $('#courses');
for(var i in myData) {
$('<li><h3>' +this.[i].chapter+ '</h3><p>' +this.title+ '</p></li>').appendTo($clist);
}
function dContent() {
var $ccontent = $('#content');
$(this.[i].content).appendTo($ccontent);
}
});
Expected result:
- General
News forum // onclick display 'Text1' in <p id="content">
- CHAPTER 1
1.1 Introduction // onclick display 'Text2' in <p id="content">
1.2 Main Idea // onclick display 'Text3' in <p id="content">
- CHAPTER 2
2.1 Architecture // onclick display 'Text4' in <p id="content">
- CHAPTER 3
3.1 Liter.overview // onclick display 'Text5' in <p id="content">
Any help would be appreciated.
UPDATE: Here is the JSFIDDLE project.
var jsonString = '[{"chapter":"General","title":"News forum","content":"Text1"},{"chapter":"CHAPTER 1","title":"1.1 Introduction","content":"Text2"},{"chapter":"CHAPTER 1","title":"1.2 Main Idea","content":"Text3"},{"chapter":"CHAPTER 2","title":"2.1 Architecture","content":"Text4"},{"chapter":"CHAPTER 3","title":"3.1 Liter.overview","content":"Text5"}]';
var myData = JSON.parse(jsonString);
var dContent = function(event) {
$ccontent.html($(this).data('content'));
}
var $clist = $('#courses');
var $ccontent = $("#content");
var html = '';
var chapterList = [];
$clist.on('click', 'li', dContent);
$.each(myData, function(index, item) {
if ($.inArray(item.chapter, chapterList) === -1) {
chapterList.push(item.chapter);
html += '<li data-content="'+ item.content +'"><h3>' + item.chapter + '</h3><p>' + item.title + '</p></li>';
}
else {
html += '<li data-content="'+ item.content +'"><p>' + item.title + '</p></li>'
}
});
$clist.html(html);
I've written a script to do this, including putting items from the same chapter together. You can see a demo fiddle here.
I used native JavaScript for most of it, with the exception of jQuery for the $(a).on('click', .. and $(document).ready to ensure compatibility. Why is it so long? Because I built the <ul> with DOM methods, instead of a html string. This made it easy to cache and append elements. Finally, the content is added via a generator function. The way I did it means the page will use slightly more memory but you can have any string that is valid in JavaScript displayed in the content section. You may want to style it with whitespace: pre-wrap; to display new lines as expected.
Anyway, here is the code
var jsonString = '[{"chapter":"General","title":"News forum","content":"Text1"},\
{"chapter":"CHAPTER 1","title":"1.1 Introduction","content":"Text2"},\
{"chapter":"CHAPTER 1","title":"1.2 Main Idea","content":"Text3"},\
{"chapter":"CHAPTER 2","title":"2.1 Architecture","content":"Text4"},\
{"chapter":"CHAPTER 3","title":"3.1 Liter.overview","content":"Text5"}]';
// the \ at line ends is to escape the new line in the string literal
var myData = JSON.parse(jsonString);
$(document).ready(function() {
var courses_ul = document.getElementById('courses'), // cache elements
content_elm = document.getElementById('content'),
i, li, h3, p, a, // vars for loop
chapters = {}, chap; // cache chapters
for (i = 0; i < myData.length; ++i) {
chap = myData[i].chapter; // shorthand since we'll use it a few times
// make <p>, <a>
p = document.createElement('p');
a = document.createElement('a'); // could append <a> to <p> here if you want
a.setAttribute('href', '#page2');
a.appendChild(document.createTextNode(myData[i].title));
// set up click
$(a).on('click', (function (content) { // generator - will give scope to
return function () { // this returned event listener.
content_elm.innerHTML = '';
content_elm.appendChild(document.createTextNode(content));
};
}(myData[i].content))); // chose `content` not `i` so no reliance on `myData`
// now check cache if chapter exists -
if (chap in chapters) { // retreive <li> for chapter from cache
li = chapters[chap]; // from cache
// append <p>, <a>
li.appendChild(p).appendChild(a);
} else { // if not in cache
li = document.createElement('li'); // make a new <li>
chapters[chap] = li; // and cache
// make & append <h3>
h3 = document.createElement('h3');
h3.appendChild(document.createTextNode(chap));
li.appendChild(h3);
// append <p>, <a> and to <ul>
courses_ul.appendChild(li).appendChild(p).appendChild(a);
}
}
});
You have an invalid JSON structure. The correct structure is below:
[
{
"chapter": "General",
"title": "News forum",
"content": "Text1"
},
{
"chapter": "CHAPTER 1",
"title": "1.1 Introduction",
"content": "Text2"
},
{
"chapter": "CHAPTER 1",
"title": "1.2 Main Idea",
"content": "Text3"
},
{
"chapter": "CHAPTER 2",
"title": "2.1 Architecture",
"content": "Text4"
},
{
"chapter": "CHAPTER 3",
"title": "3.1 Liter.overview",
"content": "Text5"
}
]
Note that comma here 3.1 Liter.overview","content":"Text5"}, in your JSON structure, it fails here
UPDATED ANSWER WITH CODE
var jsonString = '[{"chapter": "General","title": "News forum","content": "Text1"},{"chapter": "CHAPTER 1","title": "1.1 Introduction","content": "Text2"},{"chapter": "CHAPTER 1","title": "1.2 Main Idea", "content": "Text3"},{"chapter": "CHAPTER 2","title": "2.1 Architecture","content": "Text4"},{"chapter": "CHAPTER 3","title": "3.1 Liter.overview","content": "Text5"}]';
var myData = JSON.parse(jsonString);
$(document).ready(function() {
function dContent() {
$("#content").css("border","2px solid red").css("height","100px");
$("#content").html($(this).data('value'));
}
$("#courses").on('click','li', dContent)
$.each(myData, function(index,item) {
$("#courses").append("<li class='li' data-value="+item.content+">"+item.chapter+" <p>"+item.title+"</p></li>");
})
});
DEMO ON JSFIDDLE
this.[i].chapter should probably be myData[i].chapter. As it is, it's a syntax error.
Then you should rethink whether your other uses of this are correct.
Copying this into your JSFiddle and checking in jQuery as well, will make it work.
var jsonString = '[{"chapter":"General","title":"News forum","content":"Text1"},{"chapter":"CHAPTER 1","title":"1.1 Introduction","content":"Text2"},{"chapter":"CHAPTER 1","title":"1.2 Main Idea","content":"Text3"},{"chapter":"CHAPTER 2","title":"2.1 Architecture","content":"Text4"},{"chapter":"CHAPTER 3","title":"3.1 Liter.overview","content":"Text5"}]';
var myData = JSON.parse(jsonString);
$(document).ready(function() {
var $clist = $('#courses');
$.each(myData, function(i,o){
$('<li><h3>' +o.chapter+ '</h3><p>' +
'<a href="#page2" onclick="dContent(\''+o.content+'\')">' +
o.title + '</a></p></li>').appendTo($clist);
});
window.dContent = function(content) {
var $ccontent = $('#content');
$ccontent.append(content);
}
});