I have been struggling to get this right! Can anyone help me to convert this piece of MooTools js script to jquery? The script is a dynamic query constructor. The live implementation is in http://opl.bibliocommons.com/search.
The script I need to convert is below. I can understand what this script is doing, but I don't know the equivalent jquery functions which can do the same job. Any pointers on how to approach this is appreciated.
var AdvancedSearch = new Class({
Implements: [Options],
options: {
disable_form_message: "Editing this field means you won't be able to use the constructor form. Continue?"
},
initialize: function (instance, options) {
this.setOptions(options);
this.instance = $(instance);
this.query_chunks = this.instance.getElements('div.query_chunk');
this.not_chunks = this.instance.getElements('div.not_chunk');
this.instance.addEvent('submit', this.do_search.bindWithEvent(this));
this.term_count = this.query_chunks.length;
this.not_term_count = this.not_chunks.length;
this.query_field = $('custom_query');
if ($('custom_edit').value == 'false') {
this.query_field.removeEvents('focus');
this.query_field.addEvent('focus', this.disable_form_elements.bindWithEvent(this));
}
this.operation = $('operator');
if (this.operation) {
this.operation.addEvent('change', this.construct_query.bindWithEvent(this));
}
this.query_chunks.each(function (el, i) {
el.getElement('select.parameter').addEvent('change', this.construct_query.bindWithEvent(this));
el.getElement('input.operand').addEvent('keyup', this.construct_query.bindWithEvent(this));
el.getElement('input.operand').addEvent('mouseup', this.construct_query.bindWithEvent(this));
el.getElement('a.remove_btn').removeEvents('click');
el.getElement('a.remove开发者_如何学C_btn').addEvent('click', this.remove_query_part.bindWithEvent(this));
} .bind(this));
this.add_keywords = $('add_query_part');
if (this.add_keywords) {
this.add_keywords.addEvent('click', this.add_query_part.bindWithEvent(this));
}
this.not_chunks.each(function (el, i) {
el.getElement('select.not_parameter').addEvent('change', this.construct_query.bindWithEvent(this));
el.getElement('input.not_operand').addEvent('keyup', this.construct_query.bindWithEvent(this));
el.getElement('input.not_operand').addEvent('mouseup', this.construct_query.bindWithEvent(this));
el.getElement('a.not_remove_btn').removeEvents('click');
el.getElement('a.not_remove_btn').addEvent('click', this.remove_not_part.bindWithEvent(this));
} .bind(this));
this.add_not_keywords = $('add_not_part');
if (this.add_not_keywords) {
this.add_not_keywords.addEvent('click', this.add_not_part.bindWithEvent(this));
}
},
add_query_part: function (ev) {
if (ev) ev.stop();
this.query_chunks[0].addClass('removable');
var query_chunk = this.query_chunks[0].clone().set({ 'class': 'query_chunk query_piece', 'id': "query_chunk_" + (++this.term_count) }).inject($('query_parts'));
var search_param_select = query_chunk.getElement('select').set({
'class': 'parameter',
'id': 'parameter_' + this.term_count,
'style': 'margin-right:3px'
});
var keyword = query_chunk.getElement('input[type=text]').set({
'class': 'operand text',
'id': 'keyword_' + (this.term_count),
'style': 'margin-right:3px',
'value': ''
});
var remove_btn = query_chunk.getElement('a').set({
'class': 'remove_btn',
'id': 'remove_' + (this.term_count)
});
$("query_chunk_" + this.term_count).addClass('removable');
this.query_chunks.push(query_chunk);
remove_btn.addEvent('click', this.remove_query_part.bindWithEvent(this));
keyword.addEvent('keyup', this.construct_query.bindWithEvent(this));
keyword.addEvent('mouseup', this.construct_query.bindWithEvent(this));
search_param_select.addEvent('change', this.construct_query.bindWithEvent(this));
return query_chunk;
},
remove_query_part: function (ev) {
ev.stop();
var remove_index = ev.target.getParent('div').id.split("_")[2];
this.query_chunks.splice(this.query_chunks.indexOf($('query_chunk_' + remove_index)), 1);
if ($('query_chunk_' + remove_index)) {
$('query_chunk_' + remove_index).dispose();
}
this.construct_query();
if (this.query_chunks.length == 1) this.query_chunks[0].removeClass('removable');
},
add_not_part: function (ev) {
if (ev) ev.stop();
this.not_chunks[0].addClass('removable');
var query_chunk = this.not_chunks[0].clone().set({ 'class': 'not_chunk query_piece', 'id': 'not_chunk_' + (++this.not_term_count) }).inject($('not_parts'));
var search_param_select = query_chunk.getElement('select').set({ 'class': 'not_parameter', 'id': "not_parameter_" + (this.not_term_count), 'style': 'margin-right:3px' });
var keyword = query_chunk.getElement('input[type=text]').set({ 'class': 'not_operand text', 'id': 'not_keyword_' + (this.not_term_count), 'style': 'margin-right:3px', 'value': '' });
var remove_btn = query_chunk.getElement('a').set({
'class': 'not_remove_btn',
'id': 'not_remove_' + (this.not_term_count)
});
$("not_chunk_" + this.not_term_count).addClass('removable');
this.not_chunks.push(query_chunk);
remove_btn.addEvent('click', this.remove_not_part.bindWithEvent(this));
keyword.addEvent('keyup', this.construct_query.bindWithEvent(this));
keyword.addEvent('mouseup', this.construct_query.bindWithEvent(this));
search_param_select.addEvent('change', this.construct_query.bindWithEvent(this));
return query_chunk;
},
remove_not_part: function (ev) {
ev.stop();
var remove_index = ev.target.getParent('div').id.split("_")[2];
this.not_chunks.splice(this.not_chunks.indexOf($('not_chunk_' + remove_index)), 1);
$('not_chunk_' + remove_index).dispose();
this.construct_query();
if (this.not_chunks.length == 1) this.not_chunks[0].removeClass('removable');
},
disable_form_elements: function (ev) {
if (confirm(this.options.disable_form_message)) {
disable_form(this);
} else {
ev.stop();
$('advanced_search').getElement('div.queryBox').getElements('input')[1].focus();
}
},
construct_query: function (ev) {
Messages.clear();
var query_string = "";
var part_pattern = "{param}({keyword})";
var not_pattern = "-{param}({keyword})";
var operation_pattern = "{operation}";
if (this.query_chunks.length > 1) {
query_string += "(";
}
var operands = new Array();
for (var i = 0; i < this.query_chunks.length; i++) {
if (this.query_chunks[i].getElement('input.operand').value != "") {
var myObject = {
param: (this.query_chunks[i].getElement('select.parameter').value != "anywhere") ? this.query_chunks[i].getElement('select.parameter').value + ":" : "",
keyword: this.query_chunks[i].getElement('input.operand').value
};
operands.push(part_pattern.substitute(myObject));
}
}
query_string += operands.join(" " + this.operation.value + " ");
if (this.query_chunks.length > 1) {
query_string += ")";
}
var not_operands = new Array();
for (var j = 0; j < this.not_chunks.length; j++) {
if (this.not_chunks[j].getElement('input.not_operand').value != "") {
myObject = {
param: (this.not_chunks[j].getElement('select.not_parameter').value != "anywhere") ? this.not_chunks[j].getElement('select.not_parameter').value + ":" : "",
keyword: this.not_chunks[j].getElement('input.not_operand').value
};
not_operands.push(not_pattern.substitute(myObject));
}
}
if (query_string != "") query_string += " ";
query_string += not_operands.join(" ");
if (query_string != "") query_string += " ";
query_string.trim();
this.query_field.value = query_string;
}
});
function disable_form(o)
{
o.query_field.removeEvents('focus');
$('custom_edit').value = 'true';
$('advanced_search').getElement('div.queryConstructor').addClass('hide');
}
You may well be better off looking at what the script does and reimplementing it after having "grokked" jQuery.
But if you want to translate...
The first challenge you'll have is that jQuery doesn't have an analogue of the Class
feature of MooTools. I've done an implementation of Class
that's very similar to Prototype's (which MooTools' was based on) except I add a feature to make supercalls dramatically more efficient; it's in this blog post which you could probably adapt. You'll have to translates the Implements
thing (fairly certain that just becomes a superclass parameter to my equivalent).
Then:
- The fundamental difference is that MooTools extends element instances, but jQuery wraps them. All jQuery instances are basically enhanced array-like things, where the instance you're interacting with acts a bit like a set, but you can index to the actual underlying DOM element(s) via
[]
(e.g., in jQuery,var list = $('.xyz');
gives you a jQuery instance,list
, which has alength
and can be indexed into via[]
(list[0]
is the first underlying raw DOM element). So, anywhere you're accessing the raw properties of a DOM element on the MooTools-enhanced instance (e.g., something you got back from$
or$$
), either find the jQuery equivalent function or index into the jQuery object to get at the raw DOM instance. For instance, in the above, if I want the ID of the first match inlist
, I'd do eitherlist.attr('id')
or (knowing me) more likelylist[0].id
. $('foo')
becomes$('#foo')
(or$(document.getElementById('foo'))
, but that's awkward). (Only when it's a string [note the quotes]; when it's a DOM object, leave it — hence the second form.)$$
becomes$
.getElements
andgetElement
both becomefind
. (jQuery doesn't really have a concept of individual wrapped elements, just a jQuery instance with only one element inside it.)addEvent
becomesbind
.removeEvents
becomesunbind
.bind
becomesproxy
.- jQuery doesn't have a direct analog of
bindWithEvent
, but you're probably okay withproxy
for where you're using it. Double-check that you get the arguments in the order you expect. .value
becomes.val()
.set
probably becomesattr
, but with class names useaddClass
instead.
Maybe try to cut the class up into smaller chunks and tackle problems one at a time?
Also leave the mootools functionality in as you convert, and instead of $() use "jQuery()"
example
function disable_form_jquery(o)
{
jQuery(o.query_field).unbind('focus');
jQuery('#custom_edit').val('true');
jQuery('#advanced_search').children('div.queryConstructor').addClass('hide');
}
精彩评论