render view model on item click - javascript

The situation is as follows: I have a Product model which has many properties and one is a List of Photo objects, each Photo object having an ID and a Name. There is a Carousel View having a model a list of Photos. In Product View I have something like this:
#if (Model.Photos.Count > 0)
{
....
<a href="javascript:jsFunction()".......
Where in javascript,the jsFunction looks like this:
function jsFunction()
{
alert('#Html.Action("GetPhotosCarousel", Model.Photos)');
}
and the Controller function returns the partial view _PhotosCarousel.
Now, the problem that #Html.Action executes on rendering the main view, NOT ON CLICK.
How can I render the view PhotosCarousel just on click and not on displaying the page?

I would suggest removing the actual call to jsFunction from your href and then handling it with jQuery.
Click Me
$(document).ready(function(){
$("#photoCarouselHref").click(function(){
$.ajax({
url: '#Url.Action("GetPhotosCarousel"),
//other ajax settings here
});
});
});
jQuery ajax documentation here.

You can try this:
the code is ready to have multiple anchor elements:
HTML:
<div class="container">
<a href="#Url.Action("GetPhotosCarousel")"
data-id="#Model.Id"
data-name="#Model.Name"
class="call-get-photos-carousel">click</a>
<div class="result"></div>
</div>
JS:
$(document).ready(function(){
$('.call-get-photos-carousel').bind('click', function(event) {
var
_this = this,
data = {'Id': $(this).data('id'), 'Name': $(this).data('name')};
$.get($(this).attr('href'), data, function(html) {
$(_this).siblings('.result').html(html);
});
return false;
});
});
but if you only have an anchor element, you can work in this way with ID in the element:
HTML:
<div>
<a href="#Url.Action("GetPhotosCarousel")"
data-id="#Model.Id"
data-name="#Model.Name"
id="call-get-photos-carousel">click</a>
<div id="result"></div>
</div>
JS:
$(document).ready(function(){
$('#call-get-photos-carousel').bind('click', function(event) {
var
_this = this,
data = {'Id': $(this).data('id'), 'Name': $(this).data('name')};
$.get($(this).attr('href'), data, function(html) {
$('#result').html(html);
});
return false;
});
});
in both cases the action is sent to the values ​​for the Id and Name.

Related

How do I access the list element that is appended after html was created

I am adding a list element using the append function in jQuery, how do I reference this on my onclick function? Below is my code
$(function() {
let $movies = $('#showList')
let $m = $('#show')
$.ajax({
method: 'GET',
url: 'http://api.tvmaze.com/shows',
success: function(movies) {
$.each(movies, function(i, movie) {
$movies.append('<li id="list">' + movie.name + '</li>')
})
}
})
});
$('#list').on('click', 'a', function(event) {
console.log('here');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<h1 id='bruh'>TV Shows</h1>
<ul id="showList"></ul>
<div id="show"></div>
<form id="searchForm">
<input type="text" id="search_term">
<label for="text">Search</label>
<button>Submit</button>
</form>
<a id="homelink" href="#" hidden>Back to All Shows</a>
There is no message in console when I click on the link.
The attribute id should unique in a document, you can use class instead.
Try $('body').on('click', '.list a', function(event){....
Demo:
$(function() {
let $movies = $('#showList')
let $m = $('#show')
$.ajax({
method: 'GET',
url: 'http://api.tvmaze.com/shows',
success: function(movies) {
$.each(movies, function(i, movie) {
$movies.append('<li class="list">' + movie.name + '</li>')
})
}
})
});
$('body').on('click', '.list a', function(event) {
console.log('here');
event.preventDefault();//stay on the same page
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<h1 id='bruh'>TV Shows</h1>
<ul id="showList"></ul>
<div id="show"></div>
<form id="searchForm">
<input type="text" id="search_term">
<label for="text">Search</label>
<button>Submit</button>
</form>
<a id="homelink" href="#" hidden>Back to All Shows</a>
You can give the appended divs a class then call them by it like this :
$movies.append('<li class="movie" id="list">'+ movie.name +'</li>');
//then later
let movies = $('.movie');
console.log(movies);
but if you meant to execute this script right after the ajax request
then you should call a function in the ajax success since ajax is async and the moment you execute a jquery select , the elements are still not there because ajax takes more time to retrieve the data put it in the document...
you can make a getMovies() to execute there like this:
//declare this outside the ajax
let movies = []
function getMovies(){
return $('.movie');
}
then
//ajax
success: function(){
movies = getMovies(); //add this line
}
there you go now you have movies stocked inside the 'movies' array
It seems you are running into a race condition of sorts. You are building the list using an asynchronous ajax request to an API. Before that completes, you are then attaching the Javascript code to trigger an event.
What you need to do is add the callback inside of the ready block after the list data is retrieved and the list is created.

Add class/text to a jQuery element

I'm trying to clone the following HTML template and add class/text to it.
<template id="result">
<section>
<div class="alert">
<p class="someText"></p>
</div>
</section>
</template>
So the user first submits a question:
<div id="answer"></div>
<section class="row">
<form id="form" action="/" method="GET">
<div>
<input id="question" />
</div>
</form>
</section>
Then the script executes:
$(document).ready(function () {
$('#form').on('submit', function (event) {
$.ajax({
data: {...},
type: 'GET',
url: '/result'
}).done(myFunction);
});
});
And finally it clones the template (ID #result), add a class to the element containing a class alert and add some text to the element containing a class someText, and appends it to the element containing ID #answer.
function myFunction(result) {
clone = $('#result').clone();
$('.alert', clone).addClass('myClass');
$('.someText', clone).text('myText');
clone.appendTo("#answer");
}
The function executes (I added a console.log() to the end of it to be sure) but nothing is appending.
Consider the following.
function create_message(result) {
var section = $("#result").children().clone();
$('.alert', section).addClass(result.status);
$('.address', section).text(result.address);
$('.extract', section).text(result.extract);
$('.question', section).text(result.question);
section.appendTo("#answer");
}
This creates a clone of all the HTML Elements inside the Template with ID result. It then finds specific classes inside the Object section and makes changes.
You can also do the following.
section.find(".alert").addClass(result.status);
See more: https://api.jquery.com/clone/
Update
Use <template> to hold some content that will be hidden...
So if you Clone the Template and append it, it will still be hidden.
Try the following:
function myFunction(result) {
clone = $('#result > section').clone();
$('.alert', clone).addClass('myClass');
$('.someText', clone).text('myText');
clone.appendTo("#answer");
}
Update 2
I don't use <template>, so I had to re-read some stuff. It has a content portion, so it has an HTML Fragment contained within and is not like other HTML Elements, more like an iFrame. So we need to collect the content versus cloning it.
See: How to use HTML template tag with jQuery?
Here is a working example: https://jsfiddle.net/Twisty/rpd9h0mf/20/
Your code will be something more like the following.
JavaScript
$(function() {
function showResults(results) {
var clone = $($('#result').html());
$('.alert', clone).addClass(results.class);
$('.someText', clone).text(results.answer);
clone.appendTo("#answer");
}
$('#question-form').submit(function(event) {
event.preventDefault();
$.ajax({
data: {
q: $("#question").val()
},
type: 'GET',
url: '/result',
success: showResults
});
});
});
This creates a new jQuery Object based on the HTML Content of the Template. Now you can properly edit it and append it.

How to open a modal-form, execute a action in the controller, and render the result in Grails

I have a table in my gsp where each row have a button to edit. This button open a modal panel with the form to edit this row.
When I open this modal, a js function run and make an ajax call to an action of the controller, passing the id of the row.
In the controller I search for the entity and then I return it to the view. But the problem is that in the view I can't see this object..
The code I have is:
GSP:
<a href="#modal-form" data-id="${cancha?.id}" role="button" class="open-EditCanchaModal btn btn-xs btn-info" data-toggle="modal" />
Then, this modal have a g:formRemote with 4 textFields inside to edit the properties
JS:
$(document).on("click", ".open-EditCanchaModal", function () {
var canchaId = $(this).data('id');
var newData = $.post("${createLink(controller: 'cancha', action: 'selectToEdit')}/"+canchaId);
alert("dat: "+newData); // it print dat: [object Object]
alert("can: "+newData.cancha); // it print undefined
});
GRAILS:
def selectToEdit = {
Cancha cancha = Cancha.get(params.id)
println cancha // this found the correct "Cancha"
[cancha:cancha]
}
So, I want to get the Cancha in the JS, after call the method selectToEdit, to render the atributes in the textFields of the modal panel.
I'm also new to Grails.
Correct me if I'm wrong.
Returned newData will be the string format of your object.
( not a real object, think it as the output of toString() )
So, to achieve what you are trying to do.
You may use JSON encode/decode to be the bridge between JS/GRAILS.
Creating a Grail Jquery Modal Window and Form posting with ajax?
some excerpt :
"Attach Comment": function() {
//do form posting here
$.ajax({
context: $(this),
url:"${resource()}"+"/issue/attachComment",
type:"POST",
data:{"comment":$('#commentArea').val(),"id":$("#selectedIssueInstanceId").val()},
success:function(data){
if(data.success)
{
var tobeAppendeID = $("#selectedIssueInstanceId").val();
$('#'+'comment_'+tobeAppendeID).val(data.newComment);
$( this ).dialog( "close" );
}
else
{
$('#error-message').addClass('ui-state-error ui-corner-all');
$("#error-message").html(data.message).show()
$(this).dialog("close");
}
$( this ).dialog( "close" );
}

Show list without using a button, with knockout

I have this code to show a list when a button is clicked. How can I make the list show without clicking the button?
<button class="btn" type="submit" data-bind="click: getList">Get List</button>
<ul data-bind="foreach: pList">
<li>
<b data-bind="text: $data"></b>
</li>
</ul>
define(['sublime/aadConfig','knockout'], function (aconfig,ko) {
var plugins = ko.observableArray([]);
var getPlugins = function () {
plugins(aconfig.getPluginList());
};
return {
pList: plugins,
getList: getPlugins
};
});
If you want the list to load without having to click the button you just need to call getPlugins;
define(['sublime/aadConfig','knockout'], function (aconfig,ko) {
var plugins = ko.observableArray([]);
var getPlugins = function () {
plugins(aconfig.getPluginList());
};
getPlugins(); //<-- This will go populate your plugins observable, which should auto populate your list.
return {
pList: plugins,
getList: getPlugins
};
});
EDIT
If you have objects in your array then that would happen as you specified to show $data in your markup.
[{text:"someText"},{text:"someText"},{text:"someText"}] <-- this would output [object Object]
["sometext","sometext","sometext"] <-- would output "sometext"
So its sound like you need to say $data.myDesiredValue or just myDesiredValue in your markup rather than $data
a quick solution if you have jQuery but not so pretty :
$(function(){
$('button.btn').click();
});

How do you apply an item, from a list of results, to the parent Div tag for the current object?

I am trying to build a function for inserting the number of Facebook Likes into a Div tag. So far, I have a script that can get the URL from a Div tag which is inside of another Div tag called 'entry' and then have the .getJSON() method retrieve the number of Facebook likes for each entry.However, I can't get each retrieved value of Facebook Likes to insert into a Div tag for each entry. Please note, I simplified my code to where it alerts each Facebook Like value. This is what I have so far:
<div class="entry">
<div class="fburl">https://graph.facebook.com/zombies</div>
<div class="facebook-likes"></div>
</div>
<div class="entry">
<div class="fburl">https://graph.facebook.com/starwars</div>
<div class="facebook-likes"></div>
</div>
And here's my jQuery:
$(document).ready(function(){
$(".entry").each(function() {
var fbURL = $(this).find(".fburl").html();
$.getJSON(fbURL, function(fbData) {
var fbArr = fbData['likes'];
alert(fbArr);
});
});
});
​So what I am trying to do is iterate through each entry, get the Open Graph URL for it, retrieve the Likes value, and then insert it into the appropriate Div tag, so the code should render as:
<div class="entry">
<div class="fburl">https://graph.facebook.com/zombies</div>
<div class="facebook-likes">2,586 Likes</div>
</div>
<div class="entry">
<div class="fburl">https://graph.facebook.com/starwars</div>
<div class="facebook-likes">8,905,721 Likes</div>
</div>
​
​
$(document).ready(function() {
$('.entry').each(function() {
var $this = $(this),
fbURL = $this.children('.fburl').html();
$.getJSON(fbURL, function(fbData) {
$this.children('.facebook-likes').html(fbData['likes'] + ' Likes')
});
});
});
See: http://api.jquery.com/children
Demo: http://jsfiddle.net/9EALz/2/
Note: Using children() is going to be marginally more efficient than using find() as it limits the DOM traversal to a single level ( http://jsperf.com/find-vs-children/13 ). Cashing the jQuery object $(this) via var $this = $(this) is also slightly more efficient as it prevents unnecessary selector interpretation ( http://jsperf.com/jquery-cache-vs-no-chace ).
You may want this
$(document).ready(function(){
$(".entry").each(function() {
var entry=$(this), fbURL=$(".fburl", entry).html(),
el=$('.facebook-likes', entry);
$.getJSON(fbURL, function(fbData) {
el.html(numberWithCommas(fbData['likes'])+" Likes");
});
});
});​
A thousand separator function from here
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
DEMO.
Update:
Alternatively you can use this too (using data-attribute) without an extra div for fburl, i.e.
<div class="entry">
<div data-fburl="https://graph.facebook.com/zombies" class="facebook-likes"></div>
</div>
JS
$(".entry").each(function() {
var entry=$(this), fbURL = $(".facebook-likes", entry).attr('data-fburl'),
el=$('.facebook-likes', entry);
$.getJSON(fbURL, function(fbData) {
el.html(numberWithCommas(fbData['likes'])+" Likes");
});
});

Categories

Resources