I have been trying to figure out this problem I've been having all day. I will give you a simplified run down of what I have been trying to do. The user enters a number, and however much the number is, is the number of categories there are going to be on the following page. Within each category, there is an input text button, along with an "Add Textbox" button that adds additional input textboxes dynamically. However, the problem here is that each category has this same setup on the same page. For example, if the user enters the number "3", then the page will vertically load three categories looking something like the following:
Category #1
(Initial user input textbox for category #1)
("Add Textbox" button to allow user to fill out another option)
Category #2
(Initial user input textbox for category #2)
("Add Textbox" button to allow user to fill out another option)
Category #3
(Initial user input textbox for category #3)
("Add Textbox" button to allow user to fill out another option)
The struggle I have been encountering is that each category button will need to have its own function, to tell the button where to place the textbox. This coupled with the fact that the number of categories changes depending on the user's input, has made things difficult. I started with the following:
var categoryCount = <?php echo $categoryCount; ?>;
var click = {};
for (var num=1;num<=categoryCount;num++) {
var newClick = "click_" + num;
click[newClick] = function() {
// some contents when this button is clicked
};
}
This JS creates an object of functions, which in JS would be able to be accessed by doing something like the following:
click['click_' + someID]();
However, the problem is that I cannot do this using the "onclick" attribute in my HTML/PHP button. I cannot access this object of functions, and cannot call any of the individual functions, obviously. I think I am going to need to rethink all of this and start again. I just can't think of another way to get this to work. Please share your ideas with me! Your help would be greatly appreciated.
For something like this, I'd write a constructor I could use like this
var cat1 = new Category(document.body);
Luckily for you, I also wrote one as an example. See the DEMO HERE. I haven't styled it at all for the new lines etc, though.
var Category = (function () {
var categoryCount = 0;
function elem(tag) { // shortcut
return document.createElement(tag);
}
function text(str) { // shortcut
return document.createTextNode(str);
}
function Category(node) {
var self = this; // this should have been var'd, oops!!
this.categoryId = ++categoryCount;
// make add button
this.addButton = elem('button');
this.addButton.appendChild(text('Add Textbox'));
this.addButton.addEventListener('click', function () {
self.addTextbox();
});
// make wrapper
this.wrapper = elem('section');
this.wrapper.setAttribute('id', 'cat'+this.categoryId);
this.wrapper.appendChild(this.addButton);
// make textboxes
this.textboxes = [];
this.addTextbox();
// append to document
if (node) {
this.append(node);
}
}
Category.prototype.addTextbox = function () {
var e = elem('textarea');
e.setAttribute('name', 'cat-'+this.categoryId+'-textbox[]');
this.textboxes.push(e);
this.wrapper.insertBefore(e, this.addButton);
};
Category.prototype.append = function (node) {
return node.appendChild(this.wrapper);
};
return Category;
}());
Related
I have 3 links which are the names of students.On clicking a link first time or odd number time,another div which contains the details of that student appears.On clicking the same link on second time or even number time, I need to hide the student div.Its working perfectly for me using data() event of jquery.
My requirement is if I click first student link,div with the details of first student will come.If I click the second student link,details of second student will come.If I again click on first link,the student div will hide since data() is associated with it(I think so). But I want to make it displayed because,previous click was on the second link.
My html is like this
George
Leo
Kelm
My jquery:
$("#sections ").on('click','.student_link',function(){
var clicks = $(this).data('clicks');
//alert(clicks);
if (clicks) {
$("#div_students").hide();
//alert(1);
}
else
{
$("#div_students").show();
//alert(2);
}
$(this).data("clicks", !clicks);
return false;
});
That is if I click George for first time, the corresponding div of student will appear,If I click Leo without clicking George to hide the div,I need div of Leo should come.If I click George again,I need div with details of George should come.But for me the div is hiding since the variable click is already true for George.I need the div to be displayed if previous click was not on the current link.
You can use the following code:
$("#sections").on('click', '.student_link', function () {
var prevClickedId = $('#sections').data('prevId');
if (prevClickedId != $(this).attr('id')) {
// This was not the previous clicked element
} else {
// This was the previous clicked element
}
$('#sections').data('prevId', $(this).attr('id'));
return false;
});
You can so something similar to this:
$("#sections").on('click', '.student_link', function(){
if( $("#div_students").data('viewing') == $(this).attr('id') ) {
$("#div_students").hide().data('viewing', '');
}
else {
$("#div_students").show().text($(this).attr('id'));
$("#div_students").data('viewing', $(this).attr('id'));
}
return false;
});
Here's a working example: https://jsfiddle.net/7qwsguoq/
Why don't just use jquery toggle() method? it hides element when it's visible, and shows when it's hidden.
I am using Jquery-option-tree plugin on a standalone website not based on Wordpress as in example 7 on the demo page, except that I am not passing a .txt file but a PHP page is generating the array of < options > to be passed to the plugin.
http://kotowicz.net/jquery-option-tree/demo/demo.html
This perfectly works: so let's say that the user wants to select a category for a new product, the plugin suits the purpose generating a nice: " Food -> fruit -> apples " upon user clicks. (see demo page ex. 7)
What instead if a product already exists with its categories assigned? I want to show it to the user when he edit that product, preloading the tree.
I have the ids path coming from database, so it would just be a matter of having the plugin to run without the user interact, using the value I pass. I saw this question: jQuery simulate click event on select option
and tried to simulate user' click with this (and other) methods with no luck.
$('#select')
.val(value)
.trigger('click');
Here the call to the function:
$(function() {
var options = {
empty_value: '',
set_value_on: 'each',
indexed: true, // the data in tree is indexed by values (ids), not by labels
on_each_change: '/js/jquery-option-tree/get-subtree.php', // this file will be called with 'id' parameter, JSON data must be returned
choose: function(level) {
return 'Choose level ' + level;
},
loading_image: '/js/jquery-option-tree/ajax-load.gif',
show_multiple: 10, // if true - will set the size to show all options
choose: ''
};
$.getJSON('/js/jquery-option-tree/get-subtree.php', function(tree) { // initialize the tree by loading the file first
$('input[name=parent_category_id]').optionTree(tree, options);
});
});
Here you can see the plugin:
https://code.google.com/p/jquery-option-tree/
I don't know that plugin, but looking at the examples there seems to be one that fits your need; Example 6 - AJAX lazy loading & setting value on each level change.
This would, in theory, just require some config options:
preselect: {'demo6': ['220','226']}, // array of default values - if on any level option value will be in this list, it will be selected
preselect_only_once: true, // prevent auto selecting whole branch when user maniputales one of branch levels
get_parent_value_if_empty: true,
attr: "id" // we'll use input id instead of name
If this doesn't fit you need though, you could initiate it from an event, like change, keyup, etc.
$(document).on('change', '#select', function() {
$('#nextSelect').val($(this).val());
})
$(document).on('change', '#nextSelect', function() {
$('#finalInput').val($(this).val());
})
Yes, you are right Mackan ! I saw that "preselect" option but I was initially unable to use it transferring the path from database to javascript, I ended up with my "newbie" solution to match the syntax:
preselect: {'parent_category_id': [0,'2','22']},
PHP
$category_path comes from DB query and is like "0,2,76,140,"
$path = explode(',', $category_path);
$preselect="";
foreach ($path as $value) {
$int = (int)$value;
if ($int != 0) $preselect.= "'". $int ."',";
else $preselect.= $int.","; // have to do this as ZERO in my case has to be without apostrophes ''
}
$preselect = "{'parent_category_id':[".$preselect."]}"
JS
var presel= <?php echo($preselect); ?>;
var options = {
preselect: (presel),
}
Any suggestion for a better code ?
Thanks a lot !!
I have two different IDs. One auto increment (using jquery) from an ID called id="H+currentRow+"(+currentRow+ is the current row). And another that does an ajax request to PHP that appends the form with an id="Z#"(# will be depending on the ID in the database).
Ive done this:
$(document).ready(function(){
$("input").change(function(){
var sum=0;
$("[id^=H]").each(function(){
sum=sum+(+parseInt(this.value));
});
var sum2=0;
$("[id^=Z]").each(function(){
sum2=sum2+(+parseInt(this.value));
});
var total = sum + sum2;
if(isNaN(total)) {
var total = 0;
}
$("#total").text(total);
});
});
But thats not working. It works for the first fields but it work for anything else thats being appended. Anyone know whats going on and why its not working?
when you bind an event direct to an element, new elements appended to page will not trigger the event. you have to bind a parent element where inputs are appended to.
Try this bind:
$('body').on('change', 'input', function () {
// your code remain the same here...
});
you can be more specifc than body, binding the event to parent elements of input.
I'm creating a memory game using jQuery and PHP (going off a script found here), and essentially what I'm trying to do is make it so that when two cards have been matched, they both are removed. But, I'm using two different images to be paired. In HTML form, each card looks like this:
<div class="card {toggle:'imagename'}">
<div class="off"></div>
<div class="on {toggle:'imageid'}"></div>
</div>
Essentially, when two cards are chosen the jQuery is suppose to check if the id's match. Originally it was suppose to check if the images match, but being two different images I couldn't do that (it'd only display one). Below is the jQuery:
function matchingCards(event, params){
$cards = $("."+params.css_class+".on:visible");
$.each($cards, function(index, card){
var $card = $(card);
$card.trigger("card_removed");
$card.parent(".card").unbind("*").before("<div class='card_ph'></div>").remove();
$card = null;
});
$cards_left = $("#game_board>.card");
if ( $cards_left.length == 0 ){
$(document).trigger("game_won", {});
/*
* quickFlip has a problem when working in IE: when the last
* element bound was removed the problem is caused by the bound
* resize event on the window and is causing
* the end game get stuck when the game is over...
*/
$(window).unbind("resize");
}
$cards_left = $cards = null;
};
function checkCards(){
$on_cards = $("#game_board .card>.on:visible");
if ( $on_cards.length == 2 ){
$(document).trigger("player_made_move");
// Get the first object css class
var css_class = $on_cards.parent(".card").metadata()["toggle"];
var $card = $(this);
var this_card = $card.children(".on").metadata()["toggle"];
$matched_cards = $on_cards.filter("."+this_card);
var event_name = "no_match";
if ( $matched_cards.length == 2 ){
event_name = "found_match";
}
if ( css_class == css_class ){
event_name = "no_match";
}
$(document).trigger(event_name, {css_class: css_class});
$matched_cards = null;
}
clearTimeout(chk_cards_timeout);
chk_cards_timeout = null;
$on_cards = null;
};
Any help would be appreciated.
Additional information:
The pairs have the same image name I just added "_desc" to one of them for the CSS class name (i.e. one image is titled "i1" and the other "i1_desc")
When a pair is found the cards sit there, they don't reset to original position or dissapear.
Try this flow.
1.When a card is clicked...change the class with "open". When is clicked again the class is changed with default one "hidden".
...each card has an id like image_name+desc ...so 2 cards will have the same id.
2.After each click use jQuery each() function to search for "open" class and get the id of the elements.
3) Compare those two ids,if are similar use each() function again to delete the elements. If you are not using each() function you will delete only 1'st element.
ps: don't forget to count, track the ids, score..etc.
...each() function in action http://api.jquery.com/jQuery.each/
I am getting json in "data" and passing it in for loop. Onclick of buy button, it goes to the App function. On success I need to hide the buy button and display the download label.
My problem is onclick of 1st buy button, download link for both the buttons appear.
Ideally oneclick of first buy button, buy button should be hidden and download label should appear. similarly oneclick of second buy button, buy button should be hidden and download label should appear.
How do I get particular id of each button so that I can hide one at a time?
Please help me out
function (data)
{
var Class ='';
for (var i=0; i <data.length;i++)
{
Class += '<div name="buy\''+data[i].id+'\'" class="btn btn-primary btn-small" onclick="buy(\''+data[i].identifier+'\',\''+data[i].id+'\',\''+data[i].url +'\'); return false;" href=""></div><div class="download\''+data[i].id+'\'" id="download">D<span style="font-size:15px"></span></div>';
}
return Class;
}
App = function(identifier, app_id, url) {
$.ajaxSetup({
data : {
csrf_test_name : $.cookie('csrf_cookie_name')
}
});
var jqxhr = $.post(SITE_URL + 'admin/appstore/purchaseApp', {
identifier : identifier,
ap_id : ap_id
}).done(function(data1) {
obj = JSON.parse(data1);
bootbox.alert(obj.status, obj.label);
$("#download").html('<a href='+download_url+app_id+'>Download!</a>');
});
};
it is for loop am using.. am passing '; now how do I hide buy id? $("#buys"+"'"+data[i].id+"'").hide(); is this the right way? It gives me error
if you look at the actual markup generated in Class, you will see that your buy buttons don't have an id at all. perhaps something like
Class += '<div id="buy-button-'+data[i].id+'" name="...
Now you have a unique id on each button. The next part of your problem is knowing which button to remove after a successful Ajax call. You will need to include that in the data1, returned from the server. For the sake of argument, let's say the server returns the value in your data1 object as app_id. Then all you need to do is
jQuery('#buy-button-'+data1.app_id).hide();
Slightly off-topic, I'm not too keen on the way you're using single quotes in the buttons' name attributes, either, but I don't think that's relevant here.