Ajax append array data individually - javascript

I have array of data returning by Ajax and I want to show them one by one in panel, currently they are all in one panel at the same time, I wish to have multiple step of this data.
Code
HTML
<div class="panel-body">
<div class="answerPanel"></div>
</div>
Script
$.ajax({
type:'GET',
url:'{{url('dashboard/getQuizzes')}}/'+projectId,
beforeSend: function(data) {
console.log("click - ajax before send", data);
},
success:function(data){
$(data.quizzes).each(function(_, i){
$('.answerPanel').append(i.question);
});
}
});
this $('.answerPanel').append(i.question); is returning all data together in my view, I also tried this answer the only difference was it had brake line with it :)
Result
Question
My question is how can I make multi step panel with this data?
What I'm looking for is having how are you?fg (based on my screenshot) in first page then I click next button and get uid and so on...
I'm aware this question might seem silly but please try to help before giving down vote :)

Can you try the below code
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body id="banner">
<ul id="eventCal">
</ul>
<button id="clicks">Click</button>
<script type="text/javascript">
jQuery(document).ready(function($){
var quizzes = [{title:'title1',choices:[{title:'choice1'},{title:'choice2'}]},
{title:'title2',choices:[{title:'new1'},{title:'new2'}]},
{title:'title3',choices:[{title:'demo1'},{title:'demo2'}]}];
var index = 0;
console.log(quizzes.length)
$("#clicks").click(function(){
if(typeof quizzes[index] != 'undefined'){
var html = '<li><span>'+quizzes[index].title+'</span></li>';
if(quizzes[index].choices.length > 0){
html+='<li class="choises">';
quizzes[index].choices.forEach((element, index, array) => {
//console.log(element.title);
html+='<ul>';
html+='<li><span>'+element.title+'</span></li>';
html+='</ul>';
});
html+='</li>';
}
$("#eventCal").html(html);
index++;
}
if(quizzes.length === index)
$("#clicks").html("Finish");
})
});
</script>
</body>

I think iterator is exactly what you looking for. It is simple yet so elegant and powerfull:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3 id="question"></h3>
<div id="answers"></div>
<button id="nextBtn">Next question</button>
<script>
// Iterator
function iterator(array) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length
? { value: array[nextIndex++], done: false }
: { done: true };
}
};
}
$(document).ready(function() {
var quizzesArray = [
{
question: 'How are you?',
choices: [
{ choice: 'Okay' },
{ choice: 'Bad' },
{ choice: 'Who cares?' }
]
},
{
question: 'What time is it now?',
choices: [{ choice: '4pm' }, { choice: '2am' }, { choice: 'No idea' }]
},
{
question: 'What is your job?',
choices: [
{ choice: 'Student' },
{ choice: 'Teacher' },
{ choice: 'Unemployed' }
]
},
{
question: 'Why are you angry?',
choices: [
{ choice: 'I am hungry' },
{ choice: 'I lost my dog' },
{ choice: 'Not angry' }
]
}
];
// Initialize the iterator
var quiz = iterator(quizzesArray);
$('#nextBtn').click(function() {
var upNext = quiz.next();
if (upNext.done) {
return;
}
var current = upNext.value;
var answers = '';
current.choices.forEach(function(choice) {
answers += `
<p>
<input type="radio" name="answer" value="${choice.choice}">
<label>${choice.choice}</label>
</p>
`;
});
$('#question').text(current.question);
$('#answers').html(answers);
});
});
</script>

Related

Select2 group with Infinite scroll

I am using select2 group option with infinite scroll and data are coming by Ajax calling per page 10. Here is some problem arises, suppose user 1 has 15 data and user 2 has 15 data, at first 10 data are coming from user 1 and in next page 10 (5 data for user1 and 5 data for user2). no problem for data getting but the problem is user 1 group showing double. How can I prevent double display to my select2 options group? Has there any way to make an option group again?
HTML CODE
<div class="container">
<form id="frm">
<h1>Solution 1</h1>
<div class="row">
<div class="col-4">
<div class="form-group">
<label for="tagInput">Get data by ajax calling</label>
<select class="form-control" id="pictures_tag_input">
</select>
<small class="form-text text-muted"><p class="text-info">Infinite Scroll</p></small>
</div>
</div>
</div>
</form>
</div>
JS CODE
$(document).ready(function() {
// solution 1
//example.com/articles?page[number]=3&page[size]=1
http: $("#pictures_tag_input").select2({
placeholder: "Search for options",
ajax: {
url: "https://jsonplaceholder.typicode.com/users/1/todos",
dataType: "json",
global: false,
cache: true,
delay: 250,
minimumInputLength: 2,
data: function(params) {
// console.log(params.page || 1);
return {
q: params.term, // search term
_page: params.page || 1,
_limit: 10 // page size
};
},
processResults: function(data, params) {
params.page = params.page || 1;
var datx = getNestedChildren(data);
// console.log(datx);
return {
results: datx,
pagination: {
more: true
}
};
} //end of process results
} // end of ajax
});
function getNestedChildren(list) {
var roots = [];
for (i = 0; i < list.length; i += 1) {
node = list[i];
if (roots.length === 0) {
var obj = {
text: "User " + node.userId,
children: [{ id: node.id, text: node.title }]
};
roots.push(obj);
} else {
var obj = {
text: "User " + node.userId,
children: [{ id: node.id, text: node.title }]
};
var rootArray = $.map(roots, function(val, i) {
var vl = "User " + node.userId;
if (val.text === vl) return val;
else return undefined;
});
if (rootArray.length > 0) {
var obj1 = {
id: node.id,
text: node.title
};
rootArray[0].children.push(obj1);
} else {
roots.push(obj);
}
}
}
return roots;
}
});
Demo
https://codepen.io/mdshohelrana/pen/MLVZEG
Just try to use the following code
templateResult: function(data) {
if (typeof data.children != 'undefined') {
$(".select2-results__group").each(function() {
if (data.text == $(this).text()) {
return data.text = '';
}
});
}
return data.text;
}
NOTE: Need to group from server side, Other wise you have to make master details from client side.
the accepted answer didn't work for me and I don't see why should that work. A return in the $.each will not return from the templateResult() function.
Here is an approach that worked for me.
It is not necessary to build a nested list by getNestedChildren(list) on javascript side. It is much easier to build it on server side instead.
The appearance of search results in the dropdown (options and the optgroups) can be customized by using the templateResult option. I removed the duplicated optgroups and labels by this option.
check the templateResult: formatOptions, part of the code
$(document).ready(function() {
$("#pictures_tag_input").select2({
placeholder: "Search for options",
templateResult: formatOptions,
ajax: {
url: "https://jsonplaceholder.typicode.com/users/1/todos",
dataType: "json",
global: false,
cache: true,
delay: 250,
minimumInputLength: 2,
data: function(params) {
return {
q: params.term,
_page: params.page || 1,
_limit: 10
};
},
processResults: function(data, params) {
params.page = params.page || 1;
return {
results: data,
pagination: {
more: true
}
};
} //end of process results
} // end of ajax
});
function formatOptions(item, container, $el) {
// optgroups section
if (item.children && item.children.length > 0) {
// don't format the repeated optgroups!
if ($(".select2-results__group").text() === item.text) {
return;
}
if ($('[aria-label="' + item.text + '"]').length > 0) {
return;
}
// the first occasion of the given optgroup
return $el;
}
// options section
// here you can implement your own logic
// if you want to customise the output of the options
$el.addClass('something-special-result result');
return $el;
}
});
maybe the problem is a source of a data
You call user 1 .... server return a 1
You call user 2 .... server return a 1
You call user 3 .... server return a 2
You call user 4 .... server return a 2
You call user 5 .... server return a 3
You call user 6 .... server return a 3
curent_user = 1;
$(document).ready(function() {
http: $("#pictures_tag_input").select2({
placeholder: "Search for options",
ajax: {
url: "https://jsonplaceholder.typicode.com/users/1/todos",
dataType: "json",
global: false,
cache: false,
minimumInputLength: 2,
data: function(params) {
console.log("params",params || 1);
return {
q: params.term, // search term
_page: curent_user,
_limit: 10 // page size
};
},
processResults: function(data, params) {
curent_user += 2;
var datx = getNestedChildren(data);
console.log("data: ", data);
return {
results: datx,
pagination: {
more: true
}
};
} //end of process results
} // end of ajax
});
function getNestedChildren(list) {
var roots = [];
for (i = 0; i < list.length; i += 1) {
node = list[i];
if (roots.length === 0) {
var obj = {
text: "User " + node.userId,
children: [{ id: node.id, text: node.title }]
};
roots.push(obj);
} else {
var obj = {
text: "User " + node.userId,
children: [{ id: node.id, text: node.title }]
};
var rootArray = $.map(roots, function(val, i) {
var vl = "User " + node.userId;
if (val.text === vl) return val;
else return undefined;
});
if (rootArray.length > 0) {
var obj1 = {
id: node.id,
text: node.title
};
rootArray[0].children.push(obj1);
} else {
roots.push(obj);
}
}
}
return roots;
}
});
so if you skip a one step
You call user 1 .... server return a 1
You call user 3 .... server return a 2
You call user 5 .... server return a 3
I just found a better solution which does not result in a (duplicated) optgroup being rendered as an empty option:
processResults: function( json, params ){
setTimeout( function() {
var $prevOptions = false;
var $prevGroup = false;
// loop
$('.select2-results__option[role="group"]').each(function(){
// vars
var $options = $(this).children('ul');
var $group = $(this).children('strong');
// compare to previous
if( $prevGroup && $prevGroup.text() === $group.text() ) {
$prevOptions.append( $options.children() );
$(this).remove();
return;
}
// update vars
$prevOptions = $options;
$prevGroup = $group;
});
}, 1 );
return json;
}
Advanced Custom Fields uses the exact same code for their WordPress plugin in order to fix this issue, ajax-load and group posts from different post-types.

Highlight selected jsGrid row

I found this example which highlights a row after it has been selected but the problem with it is that it keeps the previous row(s) highlighted after another one has been selected.
Here's part of the code
//js
rowClick: function(args) {
var $row = this.rowByItem(args.item);
$row.toggleClass("highlight");
},
//css
tr.highlight td.jsgrid-cell {
background-color: green;
}
I can't find a solution to unhighlight the previously selected row
A little late to the party on this one, however the accepted answer by #Narenda didn't completely solve my problem. This may help someone else that stumbles across this later.
If you need a single select only, here's a way of doing it:
Extend the jsGrid plugin with a method to find a row by index:
jsGrid.Grid.prototype.rowByIndex = function(arg){
//this._content.find("tr")[arg] returns a DOM element instead of a jQuery object
//Pass the DOM element to the find method to get a jQuery object representing it
return this._content.find(this._content.find("tr")[arg]);
};
Modify the rowClick function in #Narenda's answer:
rowClick: function ( args ) {
//Deselect all rows
for(var i = 0; i<this.data.length; i++){
this.rowByIndex(i).removeClass("jsgrid-highlight-row");
}
//Everything else as per the previous answer
var $row = this.rowByItem(args.item),
selectedRow = $("#jsGrid").find('table tr.jsgrid-highlight-row');
if (selectedRow.length) {
selectedRow.toggleClass('jsgrid-highlight-row');
};
$row.toggleClass("jsgrid-highlight-row");
//Any other code to run on item click
}
And add some CSS. This mimics the row hover in the default theme:
tr.jsgrid-highlight-row td.jsgrid-cell {
background:#c4e2ff;
border-color:#c4e2ff;
}
You can achieve by this following steps
First on row click you need to get selected row like this
var selectedRow = $("#jsGrid").find('table tr.highlight').
Then you can use
selectedRow.toggleClass('highlight') or selectedRow.removeClass('highlight')
DEMO
$("#jsGrid").jsGrid({
width: "100%",
height: "auto",
paging: false,
//for loadData method Need to set auto load true
autoload: true,
noDataContent: "Directory is empty",
controller: {
loadData: function(filter) {
var data = [{
nickname: "Test",
email: "t#gmail.com"
}, {
nickname: "Test 1",
email: "t1#gmail.com"
}, {
nickname: "Test 2",
email: "t2#gmail.com"
}, {
nickname: "Test 3",
email: "t3#gmail.com"
}];
return data;
}
},
rowClick: function(args) {
var $row = this.rowByItem(args.item),
selectedRow = $("#jsGrid").find('table tr.highlight');
if (selectedRow.length) {
selectedRow.toggleClass('highlight');
};
$row.toggleClass("highlight");
},
fields: [{
name: "nickname",
type: "text",
width: 80,
title: "Name"
}, {
name: "email",
type: "text",
width: 100,
title: "Email Address",
readOnly: false
}]
});
tr.highlight td.jsgrid-cell {
background-color: green;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid-theme.min.css" />
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.js"></script>
<div id="jsGrid"></div>
If you came looking for a solution in which only 1 line is selected and which also deselects the same line, here is the solution:
selectedVal = null;
$(document).ready(function(){
jsGrid.Grid.prototype.rowByIndex = function(arg) {
//this._content.find("tr")[arg] returns a DOM element instead of a jQuery object
//Pass the DOM element to the find method to get a jQuery object representing it
return this._content.find(this._content.find("tr")[arg]);
};
});
rowClick: function (args) {
selectedVal = args.item;
let $row = this.rowByItem(args.item);
if ($row.hasClass("highlight") === false) {
//Deseleciona todas as linhas
for (let i = 0; i < this.data.length; i++) {
this.rowByIndex(i).removeClass("highlight");
}
$row.toggleClass("highlight");
} else {
selectedVal = null;
$row.toggleClass("highlight");
}
console.log(selectedVal);
}

clear input box on certain condition react

I am making a get request to a quiz api. When the user gets the answer correct the next answer is shown.
This is all working well, however I have got into some trouble when trying to clear the input box when the user gets the answer correct. I read this earlier and as far as I can tell it should be following the same logic.
Can anyone spot what is wrong here?
var Quiz = React.createClass({
getInitialState: function() {
return {
question: '',
answer: '',
value: '',
score: 0
}
},
getData: function() {
$.get('http://jservice.io/api/random', function(data){
var response = data[0];
console.log(response)
this.setState({
question: response.question,
answer: response.answer
})
}.bind(this));
},
componentDidMount: function() {
this.serverRequest = this.getData()
},
checkAnswer: function(event) {
if(event.target.value.toLowerCase() === this.state.answer.toLowerCase()) {
this.setState({
score: this.state.score + 1,
value: ''
})
this.getData();
}
},
skipQuestion: function() {
this.getData();
},
render: function() {
var value = this.state.value
return (
<div>
<p>{this.state.question}</p>
<input type='text' value={value} onChange={this.checkAnswer}/>
<p onClick={this.skipQuestion}>New question</p>
<p>{this.state.score}</p>
</div>
)
}
});
I moved this code into a jsbin and your input clearing logic is working fine. However, as #finalfreq mentioned in your implementation it's impossible to type a full answer in to the input box, each input gets recognized but is never displayed. The fix for that is shown below. The only change is adding the else case in checkAnswer:
var Quiz = React.createClass({
getInitialState: function() {
return {
question: '',
answer: '',
value: '',
score: 0
}
},
getData: function() {
$.get('http://jservice.io/api/random', function(data){
var response = data[0];
console.log(response)
this.setState({
question: response.question,
answer: response.answer
})
}.bind(this));
},
componentDidMount: function() {
this.serverRequest = this.getData()
},
checkAnswer: function(event) {
if(event.target.value.toLowerCase() === this.state.answer.toLowerCase()) {
this.setState({
score: this.state.score + 1,
value: ''
})
this.getData();
} else {
this.setState({
value: event.target.value.toLowerCase()
})
}
},
skipQuestion: function() {
this.getData();
},
render: function() {
var value = this.state.value
return (
<div>
<p>{this.state.question}</p>
<input type='text' value={value} onChange={this.checkAnswer}/>
<p onClick={this.skipQuestion}>New question</p>
<p>{this.state.score}</p>
</div>
)
}
});

ng-hide & ng-show in AngularJS

Using AngularJS I want to show and hide the data related with particular id in the toggle way.
My JSON Data format is like:
$scope.things = [{
id: 1,
data: 'One',
shown: true
}, {
id: 2,
data: 'Two',
shown: false
}, {
id: 3,
data: 'Three',
shown: true
}, ];
What I want is when click on id-1 It will show text One and Hide the others, when click on id-2 will show text Two and hide others and so on.
Here is the fiddle what I tried : jsfiddle : Demo Link
i updated your code
$scope.flipMode = function (id) {
$scope.things.forEach(function (thing) {
if(id == thing.id){
thing.shown = true;
}
else{
thing.shown = false;
}
})
};
{{thing.id}}
here is the working fiddle
It should work
$scope.flipMode = function (id) {
$scope.things.forEach(function (thing) {
if(thing.id === id) {
thing.shown = true;
return;
}
thing.shown = false;
})
};
<div ng-repeat="thing in things">
{{thing.id}}
</div>
Forked working solution: http://jsfiddle.net/nypmmkrh/
Change your scope function:
$scope.flipMode = function (id) {
$scope.things.forEach(function(thing) {
if(thing.id == id) {
thing.shown = true;
} else {
thing.shown = false;
}
});
};
And pass the id in the view:
{{thing.id}}

fadeIn and fadeOut divs based on radio button with if conditions

I really appreciate your help in advance. Can someone help me figure out why my last else if statement is not working?
I am getting an error "Uncaught TypeError: Cannot read property 'checked' of null" in the console, but only for the last else if.
//html for radio buttons
<p><input type="radio" name="radio" value="generalPurpose" id="gp-toggle"><label for="gp-toggle" >General Purpose</label></p>
<p><input type="radio" name="radio" value="client" id="cc-toggle-one"><label for="cc-toggle-one">Client</label></p>
<p><input type="radio" name="radio" value="contractor" id="cc-toggle-contractor"><label for="cc-toggle-contractor">Contractor</label></p>
<p><input type="radio" name="radio" value="urgent" id="urgent-toggle"><label for="urgent-toggle">Urgent Request</label></p>
.
///js
$(function() {
$("#contact-form .button").click(function() {
var data = {
radio: $("input:radio[name=radio]:checked").val(),
firstName: $("#f-name").val(),
lastName: $("#l-name").val(),
email: $("#email").val(),
phone: $("#phone").val(),
comments: $("#comments").val(),
coverage: $("#coverage").val(),
services: $("#services-two").val(),
covered: $("#covered").val(),
provided: $("#provided").val(),
reason: $("#reason").val()
};
$.ajax({
type: "POST",
url: "formmail.php",
data: data,
success: function() {
$('.form-inner').fadeOut(1000);
setTimeout(function() {
if (document.getElementById('gp-toggle').checked) {
$('.gp-reply').fadeIn(1000);
} else if (document.getElementById('cc-toggle-one').checked) {
$('.client-reply').fadeIn(1000);
} else if (document.getElementById('cc-toggle-two').checked) {
$('.contractor-reply').fadeIn(1000);
} else if (document.getElementById('urgent-toggle').checked) {
console.log('perform fadein');
$('.urgent-reply').fadeIn(1000);
}
}, 1200);
}
});
return false;
});
});
thanks again. I was really hoping for a stupid typo; but I guess I will need to look more into this.
so based on this question here >> Uncaught TypeError: Cannot read property 'checked' of null index.html:24 suggested by https://stackoverflow.com/users/1421098/ameya-rote
I made some variables and it seems to be working fine now.
var gp = document.getElementById('gp-toggle').checked;
var client = document.getElementById('cc-toggle-one').checked;
var contractor = document.getElementById('cc-toggle-contractor').checked;
var urgent = document.getElementById('urgent-toggle').checked;
.
$(document).ready(function() {
$(function() {
$("#contact-form .button").click(function() {
var data = {
radio: $("input:radio[name=radio]:checked").val(),
firstName: $("#f-name").val(),
lastName: $("#l-name").val(),
email: $("#email").val(),
phone: $("#phone").val(),
comments: $("#comments").val(),
coverage: $("#coverage").val(),
services: $("#services-two").val(),
covered: $("#covered").val(),
provided: $("#provided").val(),
reason: $("#reason").val()
};
$.ajax({
type: "POST",
url: "formmail.php",
data: data,
success: function() {
$('.form-inner').fadeOut(1000);
setTimeout(function() {
if ('gp') {
$('.gp-reply').fadeIn(1000);
} else if ('client') {
$('.client-reply').fadeIn(1000);
} else if ('contractor') {
$('.contractor-reply').fadeIn(1000);
} else if ('urgent') {
console.log('perform fadein');
$('.urgent-reply').fadeIn(1000);
}
}, 1200);
}
});
return false;
});
});
});
Try the code given below, Hope it will work.
function get_checked_val() {
var inputs = document.getElementsByName("selected");
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].checked) {
return inputs[i].value;
}
}
}
function onSubmit() {
var id = get_checked_val();
alert("selected input is: " + id);
}
Or you may try this to make the value checked
$(document.getElementById('cc-toggle-one')).attr('checked', true);

Categories

Resources