Showing posts with label ajax. Show all posts
Showing posts with label ajax. Show all posts

Friday, December 9, 2011

jQuery + grails and my missing buttons...

currently I'm switching miniX over to use jQueryUi style buttons, since this makes life so much easier to maintain them.

Except during my event processing my buttons keep disappearing, which is rater annoying, to say at least.

Couple of hours later I finally found a crude but working solution. I just create a simple event handler, which re renders all by buttons...


$(document).ajaxComplete(function() {
$("input:submit, a.button, input:button, div.qq-upload-button").button()
});

$(document).ready(function() {
$("input:submit, a.button, input:button, div.qq-upload-button").button()
});

Tuesday, July 28, 2009

updating more than one div with grails and ajax

sometimes it happens that you have to update several div's on one webpage, when you click on a form or a button.

Now you can either reload the complete page, which can take a while with a lot of data or just queue remote functions in a java script function like this


function addStandard() {

if (YAHOO.example.container.addstandard) {
YAHOO.example.container.addstandard.hide();
}

//get our element values
var conc = document.getElementsByName('qs_concentration')[0].value;
var pattern = document.getElementsByName('qs_pattern')[0].value;

//calls the remote functions
${remoteFunction(
controller: 'management',
action: 'addStandard_ajax',
params: '\'conc=\' + escape(conc) + \'&pattern=\' + escape(pattern)',
update: 'registered_standards')}

${remoteFunction(
controller: 'messenger',
action: 'showMessage',
params: '\'message=you should recalculate the database now!\'',
update: 'messenger')}
}

Monday, July 27, 2009

sometimes it's simpler to use plain ajax...

today I was struggling for a bit with generating the update part of a remote function on the fly and after a couple of minutes. I started thinking, do I have to really use this tag? Why don't I use just plain Ajax, since grails will generate the same code anyway.

Solution:


<div class="center">
<img name="${bin.getId()}" src="${createLinkTo(dir: 'images', file: 'remove.gif')}" alt="zoom" onclick="new Ajax.Updater

('bin-container-${db}', '/quality-war/management/remove_bin_ajax', {asynchronous:true,evalScripts:true,parameters


:'bin=${bin.getId()}&database=${db}'});"/>
</div>


this also shows how to submit several parameters at once in plain ajax style.

lesson of the day...

and god said you shall no duplicate div ids,
cause if you do,
you shall be send to the hell of css,
constant torture and misfortune will await you,

so do not duplicate your id's!

problem:

updating a you tab with some dynamic generated content, which generate the same div id over and over again...

Thursday, July 23, 2009

Grails - using several arguments with a remote function

in grails it's a bit tricky to use a remote function and pass more than one parameter, since it does not follow the map approach like the usual approach

After a bit of asking Dr Google I finally found an approach which worked


var conc = document.getElementsByName('qs_concentration')[0].value;
var pattern = document.getElementsByName('qs_pattern')[0].value;

${remoteFunction(
controller: 'management',
action: 'addStandard_ajax',
params: '\'conc=\' + escape(conc) + \'&pattern=\' + escape(pattern)',
update: 'registered_standards')}


now I just wish there would be an easier approach

grails remote function on image or checkbox

Today I was in the situation that I wanted to call a remote function on an image to emulate a button, to delete an object with a specific id.

It's simple enough,



<img name="${standard.getPosition()}" src="${createLinkTo(dir: 'images', file: 'remove.gif')}" alt="zoom" onclick="${remoteFunction(
controller: 'management',
action: 'removeStandard_ajax',
params: '\'standard=\' + + escape(this.name)',
update: 'registered_standards')}"/>


To make live easy we just save the id in the name field of the image, but you can also save it somewhere else, depending on your requirements.

Now another thing you can do is todo the same thing for checkfields.


<input type="checkbox" id="cacheSetting" name="cacheSetting" onchange="${remoteFunction(
controller: 'management',
action: 'updateCache_ajax',
params: '\'cacheSetting=\' + escape(this.checked)',
update: 'general_config')}"/>


If you want to preserve the check state you can do this with this


<input type="checkbox" id="cacheSetting" name="cacheSetting" <%if(cacheSetting) println "checked"%> onchange="${remoteFunction(
controller: 'management',
action: 'updateCache_ajax',
params: '\'cacheSetting=\' + escape(this.checked)',
update: 'general_config')}"/>


and an example controller function could look like this



def updateCache_ajax = {
assert params.cacheSetting != null, "you need to provide \"cacheSetting\" in the params object"
BinBaseQualityConnector.getQualityConfigService().setCaching(Boolean.parseBoolean(params.cacheSetting))

//define our model
def model = new HashMap()

//build the model
model.cacheSetting = BinBaseQualityConnector.getQualityConfigService().isCaching()

render(template: "general", model: model)
}

Thursday, July 9, 2009

Ajax and Grails and YUI

currently I'm trying to work more with ajax and grails.

So the first serious project is our quality control webfrontend which needs fancy stuff like

  • progress bars
  • multiple layers, cause they are hip...
and so.

So far one issue was to display a webpage in a layer on top of another webpage and the current soultion is:

controller:


class CompoundController {


/**
* shows the binbase compound
*/
def show_ajax = {
log.info("calling url...")
def id = params.id
def database = params.database

def server = System.getProperty("application.server")
def link = "http://${server}:8080/binbase-compound/bin/show/${id}?db=${database}"
//build our url
log.info("generated url: ${link}");
URL url = new URL(link)
InputStream stream = url.openStream()
Scanner scanner = new Scanner(stream)

//store the output, since this url can take a while to load, if it's not in the server cache
StringBuffer buffer = new StringBuffer()
while(scanner.hasNextLine()){
buffer.append(scanner.nextLine())
}

log.info("render result");

render "<iframe src="$%7Blink%7D" width="\"100%\"" height="\"100%\""></iframe>"
}
}

view:



<g:remotelink onloading="load();" oncomplete="done();" onsuccess="showFiles();" update="window_content" controller="compound" method="show_ajax" params="[database:database,id:id]">199651</g:remoteLink>



our div where we display the result


<div id="window">
<div class="hd"><div class="tl"></div><span></span><div class="tr"></div></div>
<div class="bd"><div id="window_content"></div></div>
</div>



and the related java script, yes I said it I'm using some javascript. Mostly the YUI library.



YAHOO.namespace("example.container");

function load() {

if (!YAHOO.example.container.wait) {

// Initialize the temporary Panel to display while waiting for external content to load

YAHOO.example.container.wait =
new YAHOO.widget.Panel("progress",
{
fixedcenter: true,
close: false,
draggable: false,
zindex:4,
modal: true,
visible: false
}
);

YAHOO.example.container.wait.setHeader("
please wait, this process can take up to 5 minutes
");
YAHOO.example.container.wait.render(document.body);

}


YAHOO.example.container.wait.show();
}

function done() {
YAHOO.example.container.wait.hide();

}

function showFiles() {

if (!YAHOO.example.container.files) {

// Initialize the temporary Panel to display while waiting for external content to load

YAHOO.example.container.files =
new YAHOO.widget.Panel("window",
{
fixedcenter: true,
close: true,
draggable: false,
zindex:5,
modal: false,
visible: false
}
);

//YAHOO.example.container.files.setHeader("Files for day...");
//YAHOO.example.container.files.setBody("<div id=\"showFiles\"></div>
");
YAHOO.example.container.files.render(document.body);

}


YAHOO.example.container.files.show();
}



and than there is some css,


#window.yui-panel .bd {
overflow: hidden;
padding: 0px;
border: 1px solid #aeaeae;
background-color: #FFF;
width:1024px;
height:600px;
}

#window.yui-panel .ft {
font-size: 75%;
color: #666;
padding: 0px;
overflow: hidden;
border: 1px solid #aeaeae;
border-top: none;
background-color: #dfdfdf;
}

#window.yui-panel .hd span {
vertical-align: middle;
line-height: 22px;
font-weight: bold;
}

#window.yui-panel .hd .tl {
width: 7px;
height: 22px;
top: 0;
left: 0px;
position: absolute;
}

#window.yui-panel .hd .tr {
width: 7px;
height: 22px;
top: 0;
right: 0px;
position: absolute;
}
#progress.yui-panel .bd {
overflow: hidden;
padding: 0px;
margin: 5px;
background-color: #FFF;
}

#progress.yui-panel .ft {
font-size: 75%;
color: #666;
padding: 0px;
overflow: hidden;

border: 1px solid #aeaeae;
border-top: none;
background-color: #dfdfdf;
}

/* Provide skin for custom elements */
#progress.yui-panel .hd span {
vertical-align: middle;
line-height: 22px;
font-weight: bold;
padding-left: 60px;
padding-right: 60px;
padding-top: 30px;
padding-bottom: 30px;
border: 1px solid #aeaeae;
background-color: #dfdfdf;
width: 120px;
height: 60px;
}

#progress.yui-panel .hd .tl {
width: 7px;
height: 22px;
top: 0;
left: 0px;
position: absolute;
}

#progress.yui-panel .hd .tr {
width: 7px;
height: 22px;
top: 0;
right: 0px;
position: absolute;



I'm still not a fan of css/js, but sometimes you gotta use what's available.